百度網(wǎng)站錄入網(wǎng)站整站優(yōu)化
1、多標簽/多窗口之間的切換
場景:
在頁面操作過程中有時候點擊某個鏈接會彈出新的窗口,這時就需要切換到新打開的窗口上進行操作。這種情況下,需要識別多標簽或窗口的情況。
操作方法:
switch_to.window()方法:切換窗口??梢詫崿F(xiàn)在不同的窗口之間切換。current_window_handle:獲得當前窗口句柄。
window_handles: 獲取所有窗口句柄。
提示:句柄就可以理解成瀏覽器窗口的id值。
操作說明:
獲取所有窗口的句柄
handles = driver.window_handlers
調(diào)用該方法會得到一個列表,在selenium運行過程中的每一個窗口,都有一個對應(yīng)的值存放在里面。
(換句話說,有多少個窗口,就有多少個句柄)
通過窗口的句柄進入的窗口
driver.switch_to_window(handles[n])
練習
"""
1.學習目標:必須掌握web中多窗口切換方法
2.語法(操作步驟)2.1 獲取當前窗口句柄driver.current_window_handle2.2 點擊頁面中的超鏈接觸發(fā)多窗口2.3 獲取所有窗口句柄driver.window_handles2.4 進入新窗口switch_to.window(handles[1])2.5 操作新窗口中的元素按實際工作需求編寫2.6 退出新窗口switch_to.window(handles[0])3.需求在頁面中,實現(xiàn)多窗口切換。
"""
# 1.導入selenium
from selenium import webdriver
import time
from selenium.webdriver.common.by import By# 2.打開瀏覽器
driver = webdriver.Chrome()#3.打開百度一下頁面
driver.get("https://www.baidu.com/")
time.sleep(2)## 4. 多窗口切換操作
# 4.1 獲取當前窗口句柄
handle = driver.current_window_handle
print('點擊之前的窗口句柄是:', handle)
print('點擊前的url:', driver.current_url)# 4.2 點擊頁面中的百度熱搜 超鏈接觸發(fā)多窗口
driver.find_element(By.XPATH,'//a[text()="新聞"]').click()
time.sleep(3)# 4.2 獲取所有窗口句柄
handles = driver.window_handles# 4.3 進入新窗口
driver.switch_to.window(handles[-1])
print('點擊之后瀏覽器所有的窗口句柄是:', handles)
print('點擊后的url:', driver.current_url)# 4.5 退出新窗口
# 你需要退到哪個窗口就寫哪個窗口的handle索引
# 因為handle在上邊賦值等于第一個窗口了,這里就可以寫handle
# 也可以寫handles[0]
driver.switch_to.window(handle)
time.sleep(10)# 5.關(guān)閉瀏覽器
driver.quit()
"""
點擊之前的窗口句柄是: 2CC28D229393F6E1A07AA345F0E2D98D
點擊前的url: https://www.baidu.com/
點擊之后瀏覽器所有的窗口句柄是: ['2CC28D229393F6E1A07AA345F0E2D98D', '6A8E0C9DD6E357F82727264A8A28C281']
點擊后的url: https://news.baidu.com/
"""
2、iframe切換
場景
頁面會進行一層一層的嵌套,只有切換到嵌套的iframe頁面,才可以定位到iframe頁面里的標簽屬性
# 1、通過name屬性進行定位,前提是iframe有name屬性
driver.switch_to.frame("login_frame")# 2、通過iframe索引去切換,注意iframe層級關(guān)系
driver.switch_to.frame(1)# 3、通過元素去定位,先找到要定位的iframe元素,然后再作為參數(shù)傳入
iframe = driver.find_element("xpath","//iframe[@id='login_frame']")
driver.switch_to.frame(iframe)# 擴展:
# 關(guān)于進入iframe頁面怎么退回到主頁面
driver.switch_to.default_content()
# 關(guān)于進入iframe頁面怎么退回到父級的iframe
driver.switch_to.parent_frame()
練習
訪問QQ郵箱為例:使用賬號密碼登錄
"""
舉例:已QQ郵箱為例
實現(xiàn)功能:使用賬號密碼登錄QQ郵箱
步驟:定位到密碼登錄的iframe中(嵌套了2層),并在該iframe中找到”密碼登錄“元素并點擊,然后到賬號密碼頁面進行輸入"""import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get("https://mail.qq.com/")#隱性等待
driver.implicitly_wait(10)# 1、通過name屬性進行定位,前提是iframe有name屬性
# driver.switch_to.frame("login_frame")# 2、通過iframe索引去切換,注意iframe層級關(guān)系
# driver.switch_to.frame(1)# 3、通過元素去定位,先找到要定位的iframe元素,然后再作為參數(shù)傳入【常用】
iframe = driver.find_element(By.XPATH, "//iframe[@class='QQMailSdkTool_login_loginBox_qq_iframe']")
driver.switch_to.frame(iframe)iframe2 = driver.find_element(By.XPATH, "//iframe[@id='ptlogin_iframe']")
driver.switch_to.frame(iframe2)
# 點擊賬號密碼登錄
driver.find_element(By.XPATH, "//a[text()='密碼登錄']").click()# 輸入賬號
driver.find_element(By.ID, "u").send_keys("username")# 輸入密碼
driver.find_element(By.ID, "p").send_keys("password")# 點擊登錄
driver.find_element(By.XPATH, "//input[@id='login_button']").click()# 強制等待5s
time.sleep(5)# 退出瀏覽器
driver.quit()
3、切換alert
accept():確定
dismiss():取消
send_keys():輸入
import time
from time import sleepfrom selenium import webdriver
from selenium.webdriver.common.by import By"""
1、某一操作導致alert(或prompt、confirm)彈窗出現(xiàn)
2、切換到彈窗中,driver.switch_to.alert 返回的是一個類的實例化對象,例如用alert接收它
"""
driver = webdriver.Chrome()
driver.get("https://www.w3school.com.cn/tiy/t.asp?f=eg_js_alert")
iframe = driver.find_element(By.XPATH,'//iframe[@id="iframeResult"]')
driver.switch_to.frame(iframe)
time.sleep(5)
# 觸發(fā)彈窗的操作
driver.find_element(By.XPATH, '//button[text()="試一試"]').click()
time.sleep(1)
# 切換到alert
alert = driver.switch_to.alert
# 關(guān)閉彈窗
alert.accept()
time.sleep(7)
driver.quit()
4、XPATH軸定位
ancestor: 祖先
parent: 父節(jié)點
following-sibling -同級的弟弟元素
preceding-sibling - 同級的哥哥元素
關(guān)系:要找的元素是已知元素的XXX關(guān)系
用法: //…已知元素/軸定位名稱::標簽名[@xx=xx]
①定位到課程人數(shù)
//p[text()=‘課程人數(shù)’]/preceding-sibling::p
②
//span[text()=“檸檬班導師ice”]/ancestor::tr//span[text()=“私信”]
或者
//span[text0=“檸檬班導師ice”]/ancestor:td/following-sibling:td//span[text0=“私信”
5、三種等待方式
①強制等待
強制等待是使線程休眠一定時間。強制等待一般在隱式等待和顯式等待都不起作用時使用。示例代碼如下:
time.sleep(3)
②隱式等待
隱式等待的作用是全局的,是作用于整個 session 的生命周期,也就是說只要設(shè)置一次隱式等待,后面就不需要設(shè)置。如果再次設(shè)置隱式等待,那么后一次的會覆蓋前一次的效果。
當在 DOM 結(jié)構(gòu)中查找元素,且元素處于不能立即交互的狀態(tài)時,將會觸發(fā)隱式等待。
driver.implicitly_wait(30)
③顯式等待
顯式等待是在代碼中定義等待條件,觸發(fā)該條件后再執(zhí)行后續(xù)代碼,就能夠根據(jù)判斷條件進行等待。程序每隔一段時間進行條件判斷,如果條件成立,則執(zhí)行下一步,否則繼續(xù)等待,直到超過設(shè)置的最長時間。核心用法如下:
# 導入顯示等待
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
...
# 設(shè)置10秒的最大等待時間,等待 (By.TAG_NAME, "title") 這個元素點擊
WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((By.TAG_NAME, "title"))
)
...
一個案例
#導入依賴
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWaitclass TestHogwarts():
def setup(self):self.driver = webdriver.Chrome()self.driver.get('https://ceshiren.com/')
#加入隱式等待self.driver.implicitly_wait(5)def teardown(self):
#強制等待time.sleep(10)self.driver.quit()def test_hogwarts(self):
#元素定位,這里的category_name是一個元組。category_name = (By.LINK_TEXT, "開源項目")
# 加入顯式等待WebDriverWait(self.driver, 10).until(expected_conditions.element_to_be_clickable(category_name))
# 點擊開源項目self.driver.find_element(*category_name).click()