文章目錄
- 前言
- 1 創建conda環境安裝Selenium庫
- 2 瀏覽器驅動下載(以Chrome和Edge為例)
- 3 基礎使用(以Chrome為例演示)
- 3.1 與瀏覽器相關的操作
- 3.1.1 打開/關閉瀏覽器
- 3.1.2 訪問指定域名的網頁
- 3.1.3 控制瀏覽器的窗口大小
- 3.1.4 前進/后退/刷新頁面
- 3.1.5 獲取網頁基本信息
- 3.1.6 打開新窗口、窗口切換
- 3.1.7 其他設置(隱藏窗口、禁用GPU加速、禁用沙盒、禁用共享內存)
- 3.2 定位并訪問、操作網頁元素
- 3.2.1 通過XPath定位網頁元素(CSDN首頁為例)
- 3.2.2 點擊元素
- 3.2.3 清空輸入框、輸入文本
- 3.2.4 獲取元素信息(文本、屬性、標簽名、大小、位置、是否顯示、是否啟用)
- 3.2.5 對元素執行鼠標操作(懸停、左鍵點擊、右鍵點擊、雙擊)
- 3.2.6 對元素執行鍵盤操作(輸入字母、空格、制表符、回車、Ctrl+...)
- 3.3 滾輪操作
- 3.4 延時等待
- 4 實戰
- 4.1 實戰一:自動化搜索并統計打印結果
- 4.2 實戰二:知網論文信息查詢
前言
- 本文介紹Windows系統下Python的Selenium庫的使用,并且附帶網頁爬蟲、web自動化操作等實戰教程,圖文詳細,內容全面。如有錯誤歡迎指正,有相關問題歡迎評論私信交流。
- 什么是Selenium庫:Selenium是一個用于Web應用程序測試和網頁爬蟲的自動化測試工具。它可以驅動瀏覽器執行特定的行為,模擬真實用戶操作網頁的場景。
- Selenium的常見用途:
- 網絡爬蟲:從動態網頁獲取信息、采集社交平臺的公開信息等,并通過程序自動處理保存。
- 自動化操作:自動完成重復的表單輸入、驗證網站各項功能是否正常運行、驗證不同瀏覽器的表現等
- 官方教程文檔:官方教程文檔
1 創建conda環境安裝Selenium庫
- conda創建一個新的python環境:
conda create -n selenium python=3.11
- 激活創建的python環境:
conda activate selenium
- 安裝selenium:
pip install selenium
2 瀏覽器驅動下載(以Chrome和Edge為例)
- 驅動的作用:驅動充當Selenium代碼和瀏覽器之間的翻譯器,其提供了統一的接口來控制不同的瀏覽器
- Selenium程序、驅動、瀏覽器之間的關系
Selenium程序 → 瀏覽器驅動 → 瀏覽器↑ ↑ ↑
發送命令 → 轉換命令 → 執行操作↓ ↓ ↓
接收結果 ← 轉換結果 ← 返回結果
- 下載Chrome瀏覽器驅動:
- 查看Chrome版本信息(打開Chrome瀏覽器 → 點擊右上角三個點 → 設置 → 關于Chrome):
我這里版本是131.0.6778.265(正式版本) - 進入下載頁面,選擇與Chrome版本最接近的驅動版本復制鏈接進行下載:
選擇與Chrome版本最接近的驅動版本,復制操作系統對應的驅動的鏈接
在瀏覽器地址欄輸入上述鏈接回車,瀏覽器會自動下載驅動
下載完成會得到這樣一個壓縮文件,這里面就是驅動:
解壓壓縮包得到這樣三個文件,記住驅動文件夾的位置:
- 查看Chrome版本信息(打開Chrome瀏覽器 → 點擊右上角三個點 → 設置 → 關于Chrome):
- 下載Edge瀏覽器驅動
-
查看Edge版本信息(打開Edge瀏覽器 → 點擊右上角三個點 → 設置 → 關于Microsoft Edge):
我這兒版本是131.0.2903.146 -
進入下載頁面,選擇與Edge版本最接近的版本點擊對應的下載按鈕即可:
得到如下壓縮包:
解壓后得到如下文件,記住驅動的位置:
-
3 基礎使用(以Chrome為例演示)
3.1 與瀏覽器相關的操作
3.1.1 打開/關閉瀏覽器
- webdriver.Chrome():初始化并打開瀏覽器
- quit():關閉瀏覽器
# 導入必要的庫
from selenium import webdriver # Selenium的核心包
from selenium.webdriver.chrome.service import Service # Chrome驅動服務類# 設置ChromeDriver路徑
# driver_path指定了ChromeDriver可執行文件的本地路徑
# Service類用于創建ChromeDriver服務實例
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化Chrome瀏覽器
# webdriver.Chrome()會啟動一個新的Chrome瀏覽器實例
# service參數告訴Selenium使用哪個ChromeDriver服務
browser = webdriver.Chrome(service=service)# 關閉瀏覽器
# quit()方法會完全關閉瀏覽器及其所有相關進程
browser.quit()
3.1.2 訪問指定域名的網頁
- get():打開網頁
# 導入和初始化部分與3.1相同
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Servicedriver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)
browser = webdriver.Chrome(service=service)# 使用get()方法訪問指定URL
# get()方法會等待頁面加載完成后才繼續執行后續代碼
browser.get("https://www.baidu.com")# time.sleep()添加延時
# 程序會在此處暫停5秒,方便觀察頁面加載情況
# 注意:在實際項目中應該使用顯式等待或隱式等待替代sleep
time.sleep(5)# 關閉瀏覽器
browser.quit()
3.1.3 控制瀏覽器的窗口大小
- set_window_size():設置窗口的固定長寬
- maximize_window():最大化窗口
- minimize_window():最小化窗口
- fullscreen_window():全屏顯示窗口
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)# 打開百度
browser.get("https://www.baidu.com")# 方法1:設置固定大小
browser.set_window_size(800, 600) # 設置為800x600像素
time.sleep(2) # 等待2秒觀察效果# 方法2:最大化窗口
browser.maximize_window()
time.sleep(2)# 方法3:最小化窗口
browser.minimize_window()
time.sleep(2)# 方法4:全屏顯示
browser.fullscreen_window()
time.sleep(2)# 獲取當前窗口大小
window_size = browser.get_window_size()
print(f"當前窗口大小:寬度={window_size['width']}px,高度={window_size['height']}px")# 關閉瀏覽器
browser.quit()
3.1.4 前進/后退/刷新頁面
- back():后退
- forward():前進
- refresh():刷新
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)# 訪問第一個頁面:百度
browser.get("https://www.baidu.com")
time.sleep(2) # 等待頁面加載# 訪問第二個頁面:必應
browser.get("https://www.bing.com")
time.sleep(2)# 后退到百度
browser.back()
time.sleep(2)
print("當前頁面標題:", browser.title) # 顯示當前頁面標題,驗證是否回到百度# 前進到必應
browser.forward()
time.sleep(2)
print("當前頁面標題:", browser.title) # 顯示當前頁面標題,驗證是否前進到必應# 刷新當前頁面
browser.refresh()
time.sleep(2)# 關閉瀏覽器
browser.quit()
3.1.5 獲取網頁基本信息
- title():獲取網頁標題
- current_url():獲取當前網址
- name():獲取瀏覽器名稱
- page_source():獲取頁面源碼
- window_handles():獲取所有窗口句柄
- current_window_handle():獲取當前窗口句柄
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)# 訪問百度
browser.get("https://www.baidu.com")
time.sleep(2) # 等待頁面加載# 1. 獲取網頁標題
title = browser.title
print("網頁標題:", title)# 2. 獲取當前網址
current_url = browser.current_url
print("當前網址:", current_url)# 3. 獲取瀏覽器名稱
browser_name = browser.name
print("瀏覽器名稱:", browser_name)# 4. 獲取頁面源碼(前50個字符)
page_source = browser.page_source
print("頁面源碼(前50個字符):", page_source[:50])# 5. 獲取當前窗口句柄
current_handle = browser.current_window_handle
print("當前窗口句柄:", current_handle)# 6. 獲取所有窗口句柄
all_handles = browser.window_handles
print("所有窗口句柄:", all_handles)# 7. 獲取瀏覽器的能力(capabilities)
capabilities = browser.capabilities
print("瀏覽器版本:", capabilities.get('browserVersion', 'Unknown'))
print("瀏覽器名稱:", capabilities.get('browserName', 'Unknown'))
print("平臺名稱:", capabilities.get('platformName', 'Unknown'))# 關閉瀏覽器
browser.quit()
3.1.6 打開新窗口、窗口切換
在Selenium中,我們可以通過以下方法實現窗口切換:
- window_handles:獲取所有窗口句柄
- current_window_handle:獲取當前窗口句柄
- switch_to.window():切換到指定窗口
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.baidu.com")try:# 1. 獲取初始窗口句柄main_window = browser.current_window_handleprint("主窗口句柄:", main_window)# 2. 打開新窗口(點擊鏈接在新窗口打開)browser.execute_script("window.open('https://www.bing.com', '_blank');")time.sleep(2)# 3. 獲取所有窗口句柄all_handles = browser.window_handlesprint("所有窗口句柄:", all_handles)# 4. 切換到新窗口(最后打開的窗口)browser.switch_to.window(all_handles[-1])print("當前頁面標題:", browser.title) # 應顯示必應的標題time.sleep(2)# 5. 切回主窗口browser.switch_to.window(main_window)print("切回主窗口,當前頁面標題:", browser.title) # 應顯示百度的標題time.sleep(2)# 6. 遍歷所有窗口示例print("\n遍歷所有窗口:")for handle in all_handles:browser.switch_to.window(handle)print(f"窗口句柄: {handle}")print(f"頁面標題: {browser.title}")print(f"當前URL: {browser.current_url}")print("---")time.sleep(1)except Exception as e:print(f"發生錯誤: {e}")finally:browser.quit()
3.1.7 其他設置(隱藏窗口、禁用GPU加速、禁用沙盒、禁用共享內存)
- add_argument():添加一些其他設置選項。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options # 導入 Options# 配置無頭瀏覽器、禁用GPU加速、禁用沙盒、禁用共享內存
chrome_options = Options()
chrome_options.add_argument('--headless') # 啟用無頭模式
chrome_options.add_argument('--disable-gpu') # 禁用GPU加速
chrome_options.add_argument('--no-sandbox') # 禁用沙盒
chrome_options.add_argument('--disable-dev-shm-usage') # 禁用共享內存# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器時傳入配置
browser = webdriver.Chrome(service=service, options=chrome_options)try:# 設置隱式等待時間browser.implicitly_wait(10)# 打開必應搜索頁面browser.get("https://www.bing.com")print("已打開必應搜索頁面")except Exception as e:print(f"發生錯誤: {e}")finally:browser.quit()print("瀏覽器已關閉")
3.2 定位并訪問、操作網頁元素
- 網頁元素是構成網頁的基本組成部分,是HTML文檔中的各種標簽所創建的對象。在自動化測試和網頁操作中,我們需要定位元素以便進行交互操作,獲取其相關信息。
- Selenium定位網頁元素的方法:
- ID定位:find_element(By.ID, “element-id”)
- 名稱定位:find_element(By.NAME, “element-name”)
- 類名定位:find_element(By.CLASS_NAME, “class-name”)
- 標簽名定位:find_element(By.TAG_NAME, “tag-name”)
- XPath定位:find_element(By.XPATH, “//xpath-expression”)
- CSS選擇器定位:find_element(By.CSS_SELECTOR, “css-selector”)
- 鏈接文本定位:find_element(By.LINK_TEXT, “link-text”)
- 部分鏈接文本定位:find_element(By.PARTIAL_LINK_TEXT, “partial-text”)
3.2.1 通過XPath定位網頁元素(CSDN首頁為例)
XPath是一種在XML和HTML文檔中查找元素的強大語言,其結合瀏覽器不用去看網頁源碼就能很方便的定位網頁元素。
-
首先通過瀏覽器打開需要定位的元素所在的網頁:
-
按F12進入開發者模式,點擊圖中開發者窗口左上角的圖標,點擊元素,這時鼠標滑過網頁的每一個元素下面的源碼都會快速定位到該元素的對應源碼
-
這時我們把鼠標移動到需要定位的元素上面,點擊鼠標左鍵,然后鼠標移動到該元素的源碼部分,鼠標右鍵單擊打開菜單,在菜單中選擇復制-復制XPath(或者復制完整 XPath)即可得到該元素的XPath
-
有了元素的XPath,便可以通過selenium的find_element方法獲取這個元素,隨后對其進行交互操作、獲取相關信息等。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Servicedef locate_search_button():# 設置 ChromeDriver 的路徑driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開browser = webdriver.Chrome(service=service)browser.get("https://www.csdn.net/")# 通過xpath定位搜索按鈕element = browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]/span')# 打印元素文本print("找到搜索按鈕,文本內容:", element.text)# 關閉瀏覽器browser.quit()if __name__ == "__main__":locate_search_button()
3.2.2 點擊元素
- click():點擊元素
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.csdn.net/")try:# 定位并點擊搜索按鈕search_button = browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]')search_button.click()print("成功點擊搜索按鈕")except Exception as e:print(f"發生錯誤: {e}")finally:import timetime.sleep(2) # 等待2秒看效果browser.quit()
3.2.3 清空輸入框、輸入文本
- clear():清空輸入框
- send_keys():輸入文本
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.csdn.net/")try: # 定位搜索框search_input = browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]')# 清空輸入框search_input.clear()# 輸入文本search_input.send_keys("Python Selenium")print("成功輸入文本")except Exception as e:print(f"發生錯誤: {e}")finally:import timetime.sleep(2) # 等待2秒看效果browser.quit()
3.2.4 獲取元素信息(文本、屬性、標簽名、大小、位置、是否顯示、是否啟用)
- text():獲取元素文本
- get_attribute():獲取元素某些屬性
- tag_name():獲取元素標簽名
- size():獲取元素大小
- location():獲取元素位置
- is_displayed():判斷元素是否顯示
- is_enabled():判斷元素是否啟用
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.csdn.net/")try:# 定位搜索按鈕element = browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]')# 獲取元素的各種屬性print("元素文本:", element.text)print("class屬性:", element.get_attribute("class"))print("標簽名:", element.tag_name)print("元素大小:", element.size)print("元素位置:", element.location)print("是否顯示:", element.is_displayed())print("是否啟用:", element.is_enabled())except Exception as e:print(f"發生錯誤: {e}")finally:import timetime.sleep(2)browser.quit()
3.2.5 對元素執行鼠標操作(懸停、左鍵點擊、右鍵點擊、雙擊)
使用 ActionChains 類可以對元素執行以下鼠標操作:
- move_to_element():鼠標懸停
- click():鼠標左鍵點擊
- context_click():鼠標右鍵點擊
- double_click():鼠標雙擊
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.csdn.net/")try:# 定位搜索按鈕element = browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]')# 創建 ActionChains 對象actions = ActionChains(browser)# 鼠標懸停actions.move_to_element(element).perform()print("執行鼠標懸停")time.sleep(1)# 鼠標點擊actions.click(element).perform()print("執行鼠標點擊")time.sleep(1)# 鼠標右鍵actions.context_click(element).perform()print("執行鼠標右鍵")time.sleep(1)# 雙擊actions.double_click(element).perform()print("執行鼠標雙擊")except Exception as e:print(f"發生錯誤: {e}")finally:import timetime.sleep(2)browser.quit()
3.2.6 對元素執行鍵盤操作(輸入字母、空格、制表符、回車、Ctrl+…)
使用 Keys 類可以執行以下鍵盤操作:
- send_keys():輸入文本
- Keys.BACK_SPACE:退格鍵
- Keys.SPACE:空格鍵
- Keys.TAB:制表鍵
- Keys.ENTER/Keys.RETURN:回車鍵
- Keys.CONTROL + ‘a’:全選(Ctrl+A)
- Keys.CONTROL + ‘c’:復制(Ctrl+C)
- Keys.CONTROL + ‘v’:粘貼(Ctrl+V)
- Keys.CONTROL + ‘x’:剪切(Ctrl+X)
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.csdn.net/")try: # 定位搜索框search_input = browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]')# 1. 基本輸入search_input.send_keys("Python")print("輸入文本:Python")time.sleep(1)# 2. 空格search_input.send_keys(Keys.SPACE)search_input.send_keys("Selenium")print("輸入空格和文本:Python Selenium")time.sleep(1)# 3. 全選文本 (Ctrl+A)actions = ActionChains(browser)actions.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform()print("全選文本")time.sleep(1)# 4. 復制文本 (Ctrl+C)actions.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()print("復制文本")time.sleep(1)# 5. 刪除文本(退格鍵)search_input.send_keys(Keys.BACK_SPACE)print("刪除文本")time.sleep(1)# 6. 粘貼文本 (Ctrl+V)actions.key_down(Keys.CONTROL).send_keys('v').key_up(Keys.CONTROL).perform()print("粘貼文本")time.sleep(1)# 7. 制表鍵search_input.send_keys(Keys.TAB)print("按下Tab鍵")time.sleep(1)# 8. 回車搜索search_input.send_keys(Keys.RETURN)print("按下回車鍵執行搜索")except Exception as e:print(f"發生錯誤: {e}")finally:import timetime.sleep(2)browser.quit()
3.3 滾輪操作
- 最常用且最可靠的方法是使用 JavaScript 來控制滾動
- execute_script():執行JavaScript腳本
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)
browser.get("https://www.csdn.net/")try:# 1. 滾動到頁面底部browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")print("滾動到頁面底部")time.sleep(1)# 2. 滾動到頁面頂部browser.execute_script("window.scrollTo(0, 0);")print("滾動到頁面頂部")time.sleep(1)# 3. 向下滾動500像素browser.execute_script("window.scrollBy(0, 500);")print("向下滾動500像素")time.sleep(1)# 4. 使用 PageDown 鍵滾動actions = ActionChains(browser)actions.send_keys(Keys.PAGE_DOWN).perform()print("使用 PageDown 鍵滾動")time.sleep(1)# 5. 滾動到特定元素try:element = browser.find_element(By.CLASS_NAME, "toolbar-container")browser.execute_script("arguments[0].scrollIntoView();", element)print("滾動到特定元素位置")time.sleep(1)except Exception as e:print(f"未找到目標元素: {e}")# 6. 平滑滾動到底部browser.execute_script("""window.scrollTo({top: document.body.scrollHeight,behavior: 'smooth'});""")print("平滑滾動到底部")time.sleep(2)# 7. 模擬無限滾動加載last_height = browser.execute_script("return document.body.scrollHeight")scroll_attempts = 3 # 限制滾動次數,避免無限循環for i in range(scroll_attempts):browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")print(f"執行第 {i+1} 次滾動加載")time.sleep(2)new_height = browser.execute_script("return document.body.scrollHeight")if new_height == last_height:print("已到達頁面底部")breaklast_height = new_heightexcept Exception as e:print(f"發生錯誤: {e}")finally:time.sleep(2)browser.quit()
3.4 延時等待
- implicitly_wait:設置隱式等待時間。隱式等待是一個全局設置,設置后對整個瀏覽器會話中的所有操作都生效;它告訴WebDriver在查找元素時,如果元素不存在,應該等待多長時間;在設定的時間內,WebDriver會定期重試查找元素的操作。
- WebDriverWait:創建顯式等待對象。它允許我們設置最長等待時間和檢查的時間間隔;與隱式等待不同,顯式等待可以針對特定元素設置具體的等待條件;它提供了更精確的等待控制。
- until:等待直到條件滿足。它接受一個期望條件(EC)作為參數,在超時之前反復檢查該條件是否滿足;如果條件滿足則返回結果,如果超時則拋出TimeoutException異常。
- until_not:等待直到條件不滿足。與until相反,它等待一個條件變為false;常用于等待某個元素消失或某個狀態結束的場景。
- expected_conditions:預定義的期望條件集合。包含多種常用的等待條件,如:
- presence_of_element_located:等待元素在DOM中出現
- visibility_of_element_located:等待元素可見
- element_to_be_clickable:等待元素可點擊
- all_of:等待多個條件同時滿足
- poll_frequency:設置輪詢頻率。定義了在顯式等待過程中檢查條件的時間間隔;默認是0.5秒檢查一次;可以根據實際需求調整以優化性能。
- ignored_exceptions:設置要忽略的異常。在等待過程中可以指定某些異常被忽略而繼續等待;常用于處理特定的臨時性錯誤,如StaleElementReferenceException。
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)try:# 1. 設置隱式等待時間(全局設置)browser.implicitly_wait(10)print("設置隱式等待時間:10秒")# 打開測試網頁browser.get("https://www.csdn.net/")# 2. 顯式等待 - 等待特定元素可見try:search_input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "toolbar-search-input")))print("成功找到搜索框元素")except TimeoutException:print("等待搜索框超時")# 3. 顯式等待 - 等待元素可點擊try:login_button = WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.CLASS_NAME, "login-btn")))print("登錄按鈕可以點擊")except TimeoutException:print("等待登錄按鈕可點擊超時")# 4. 自定義等待條件def custom_condition(driver):element = driver.find_element(By.CLASS_NAME, "toolbar-container")return element.is_displayed() and element.get_attribute("style") != "display: none;"try:WebDriverWait(browser, 8).until(custom_condition)print("自定義條件滿足")except TimeoutException:print("等待自定義條件超時")# 5. 多條件組合等待try:# 等待多個條件都滿足wait = WebDriverWait(browser, 10)condition = wait.until(EC.all_of(EC.presence_of_element_located((By.CLASS_NAME, "toolbar-container")),EC.visibility_of_element_located((By.ID, "toolbar-search-input"))))print("多個條件都滿足")except TimeoutException:print("等待多個條件超時")# 6. 使用until_not等待條件不成立try:# 等待加載動畫消失loading_spinner = WebDriverWait(browser, 5).until_not(EC.presence_of_element_located((By.CLASS_NAME, "loading-spinner")))print("加載動畫已消失")except TimeoutException:print("等待加載動畫消失超時")# 7. 帶有輪詢間隔的等待try:# 設置輪詢間隔為0.5秒wait = WebDriverWait(browser, timeout=10, poll_frequency=0.5)element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "toolbar-container")))print("使用自定義輪詢間隔成功找到元素")except TimeoutException:print("使用自定義輪詢間隔等待超時")# 8. 忽略特定異常的等待try:# 忽略 StaleElementReferenceException 異常wait = WebDriverWait(browser, 10, ignored_exceptions=[NoSuchElementException])element = wait.until(EC.presence_of_element_located((By.ID, "toolbar-search-input")))print("忽略特定異常后成功找到元素")except TimeoutException:print("忽略特定異常后等待超時")except Exception as e:print(f"發生錯誤: {e}")finally:time.sleep(2)browser.quit()
4 實戰
4.1 實戰一:自動化搜索并統計打印結果
- 本代碼演示打開bing搜索界面搜索關鍵詞“CSDN”,獲取搜索結果并打印每個結果的基本信息。
- 代碼思路:
- 使用
get()
方法打開bing搜索界面 - 使用
find_element()
方法定位搜索輸入框元素 - 使用
send_keys()
方法輸入關鍵字和回車按鍵執行搜索 - 使用
find_elements()
方法通過"b_algo"類名進行篩選,查看搜索界面源碼可以知道搜索結果元素都是"b_algo"類。 - 綜合使用
find_element()
、text()
、get_attribute()
方法獲取每個搜索結果的標題、鏈接、描述等信息,所使用的屬性值、類名也是通過查看源碼獲得的,通過前文介紹的元素定位方法可以很容易的知道。
- 使用
- 注意:由于不同搜索結果之間存在一定的差異,所以不一定每一個搜索結果都能獲得完整的信息,這個需要自己結合源碼對示例代碼進行修改。
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器并打開
browser = webdriver.Chrome(service=service)try:# 設置隱式等待時間browser.implicitly_wait(10)# 打開必應搜索頁面browser.get("https://www.bing.com")print("已打開必應搜索頁面")# 查找搜索框并輸入關鍵詞search_input = browser.find_element(By.ID, "sb_form_q")search_input.send_keys("CSDN")search_input.send_keys(Keys.RETURN)print("已輸入搜索關鍵詞:CSDN")# 稍等待搜索結果加載time.sleep(2)# 獲取搜索結果search_results = browser.find_elements(By.CLASS_NAME, "b_algo")print(f"\n找到 {len(search_results)} 條搜索結果:\n")# 打印搜索結果for index, result in enumerate(search_results, 1):try:# 獲取標題和鏈接title_element = result.find_element(By.CSS_SELECTOR, "h2 a")title = title_element.textlink = title_element.get_attribute("href")# 獲取描述 (直接獲取 b_caption 的文本內容)description = result.find_element(By.CLASS_NAME, "b_caption").text# 打印結果print(f"結果 {index}:")print(f"標題: {title}")print(f"鏈接: {link}")print(f"描述: {description}")print("-" * 80)except Exception as e:print(f"處理第 {index} 條結果時出錯: {str(e)}")continueexcept Exception as e:print(f"發生錯誤: {e}")finally:# 等待一段時間后關閉瀏覽器time.sleep(2)browser.quit()print("瀏覽器已關閉")
4.2 實戰二:知網論文信息查詢
- 本代碼演示打開知網高級檢索界面,通過設置學科專業(計算機)和學校單位(北京郵電大學)進行論文檢索,并按下載量排序獲取前20條論文的詳細信息。
- 代碼思路:
- 使用get()方法打開知網高級檢索界面
- 使用maximize_window()方法將窗口最大化,確保所有元素可見
- 通過XPATH定位并點擊"學科專業導航",清除已選學科,展開工學類別并選中計算機專業
- 使用send_keys()方法在學校單位輸入框中填入"北京郵電大學"
- 點擊檢索按鈕開始搜索
- 點擊下載量排序選項,對結果進行排序
- 使用execute_script()方法控制頁面向下滾動700像素
- 使用循環遍歷前20條搜索結果,通過XPATH定位每條論文的各項信息
- 注意事項:
- 代碼中使用了多處time.sleep()來確保頁面加載完成,實際使用時可根據網絡情況調整等待時間
- XPATH路徑的獲取是通過瀏覽器開發者工具復制得到,需要注意網頁結構變化可能導致定位失效
- 使用try-except結構進行異常處理,確保程序運行的穩定性
- 最后使用quit()方法關閉瀏覽器,釋放資源
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service# 設置 ChromeDriver 的路徑
driver_path = "E:\\ProgramFiles\\_CodeTools\\ChromeDriver\\chromedriver.exe"
service = Service(driver_path)# 初始化 Chrome 瀏覽器
browser = webdriver.Chrome(service=service)try:# 設置隱式等待時間browser.implicitly_wait(10)browser.get("https://epub.cnki.net/kns/advsearch?classid=RDS33BAY")time.sleep(1)# 窗口最大化browser.maximize_window()time.sleep(1)# 點擊學科專業導航browser.find_element(By.XPATH, '//*[@id="XuekeNavi_Div"]/div/div/div/div/div[1]/a[2]').click()time.sleep(1)# 點擊清除取消所有選中的學科browser.find_element(By.XPATH, '//*[@id="XuekeNavi_Div"]/div/div/div/div/div[2]/a[2]').click()time.sleep(1)# 點擊展開工學browser.find_element(By.XPATH, '//*[@id="08"]').click()time.sleep(1)# 點擊選中計算機browser.find_element(By.XPATH, '//*[@id="9UG2UB8R"]/li[8]/ul/li[12]/div/i[2]').click()time.sleep(1)# 往學校單位輸入框填寫內容browser.find_element(By.XPATH, '//*[@id="inputAndSelect"]/input').send_keys("北京郵電大學")time.sleep(1)# 點擊檢索按鈕browser.find_element(By.XPATH, "/html/body/div[2]/div[3]/div/div[3]/div[1]/div[2]/div[1]/div[9]").click()time.sleep(1)# 點擊按照下載量排序browser.find_element(By.XPATH, '//*[@id="orderList"]/li[6]').click()time.sleep(1)# 向下翻動700pxbrowser.execute_script("window.scrollBy(0, 700);")time.sleep(1)for i in range(20):title = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[2]/a',).textdetail_link = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[2]/a',).get_attribute("href")author = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[3]/a',).textinstitution = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[4]/a/font',).textdegree = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[5]',).textyear = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[6]',).textcited_count = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[7]',).textdownload_count = browser.find_element(By.XPATH,f'//*[@id="gridTable"]/div/div[2]/div/table/tbody/tr[{i+1}]/td[8]',).textprint(f"-----------------------第{i+1}條數據:")print(f"標題:{title}")print(f"詳情鏈接:{detail_link}")print(f"作者:{author}")print(f"機構:{institution}")print(f"學位:{degree}")print(f"年份:{year}")print(f"被引次數:{cited_count}")print(f"下載次數:{download_count}")except Exception as e:print(f"發生錯誤: {e}")finally:browser.quit()print("瀏覽器已關閉")