1、簡介
selenium最初是一個自動化測試工具,而爬蟲中使用它主要是為了解決requests無法直接執行JavaScript代碼的問題,因為有些網頁數據是通過JavaScript動態加載的。selenium本質是通過驅動瀏覽器,完全模擬瀏覽器的操作,比如輸入、點擊、跳轉等,來拿到網頁渲染之后的結果,可以支持多種瀏覽器。
2、環境安裝
?2.1、安裝selenium庫
pip install selenium
2.2、安裝瀏覽器驅動
我一般使用谷歌瀏覽器,因為谷歌瀏覽器的檢查功能很好用。
1、查看本地Chrome瀏覽器版本
在瀏覽器的地址欄輸入chrome://version,即可查看瀏覽器版本號
2、根據瀏覽器版本號下載對應的驅動程序
驅動程序下載地址:ChromeDriver 下載 - 最新版本 | ChromeDriver 驅動
?下載壓縮包后解壓到對應的文件夾
2.3、測試
運行下面的python腳本,觀察到谷歌瀏覽器自動打開并且訪問百度首頁停留10s退出即表示selenium環境安裝完成。
import timefrom selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Servicechrome_options = Options()
# 設置瀏覽器窗口最大化
chrome_options.add_argument("--start-maximized")
# 設置驅動路徑
chromedriver_path = '你的chromedriver.exe文件所在的路徑'
service = Service(executable_path=chromedriver_path)driver = webdriver.Chrome(service=service, options=chrome_options)url = 'https://www.baidu.com/'driver.get(url)time.sleep(10)driver.quit()
3、自動更新谷歌瀏覽器驅動
selenium程序的正確運行需要谷歌瀏覽器和瀏覽器驅動版本號匹配,由于谷歌瀏覽器會自動更新導致需要經常手動更換瀏覽器驅動。
我在網上搜索嘗試了很多關閉谷歌瀏覽器自動更新的辦法,一直沒有起作用。我們從另一個角度:編寫程序自動更新瀏覽器驅動來解決需要手動更新的問題。
3.1、檢查當前谷歌瀏覽器和瀏覽器驅動是否匹配
def test_chrome_driver():# 當前谷歌瀏覽器的驅動路徑driver_path = '你的chromedriver.exe文件所在的路徑'# 初始化chrome瀏覽器的選項chrome_options = Options()# 設置瀏覽器窗口最大化chrome_options.add_argument("--start-maximized")service = Service(executable_path=driver_path)driver = Nonetry:# 創建webdriver對象,傳入配置好的options和servicedriver = webdriver.Chrome(service=service, options=chrome_options)url = "https://www.baidu.com/"driver.get(url)print("當前谷歌瀏覽器版本號和驅動版本號匹配")except Exception as e:# 使用正則表達式從異常信息中提取谷歌瀏覽器版本號pattern = r"Current browser version is (\d+\.\d+\.\d+\.\d+)"match = re.search(pattern, str(e))if match:browser_version = match.group(1)print(f"當前谷歌瀏覽器版本號和驅動版本號不匹配,谷歌瀏覽器版本號為:{browser_version}")return browser_versionfinally:if driver:driver.quit()
匹配運行結果:
不匹配運行結果:
3.2、自動下載對應的谷歌瀏覽器驅動程序
3.2.1、方法一
解析ChromeDriver 下載 - 最新版本 | ChromeDriver 驅動,找到對應版本的驅動程序下載地址
1、瀏覽器版本號和驅動版本號不一定完全相同,一般版本號前三部分相同即可。與瀏覽器版本號前三部分相同的驅動一般有多個,為了保險起見,我們通過一個列表存儲可能匹配的驅動程序下載位置。
2、該網站提供適用于不同系統的驅動程序下載地址,我需要的是后綴為"chromedriver-win64.zip"的下載地址,你可以根據需求自行修改。因為可以下載的驅動版本號有多個,所以可以下載的地址也有多個,保存到一個列表中。
def find_chromedriver_url(browser_version):parts1 = browser_version.split('.')url = "https://www.chromedriverdownload.net/zh/"headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'}response = requests.get(url=url,headers=headers)# 檢查請求是否成功if response.status_code == 200:tree = etree.HTML(response.text)# 存儲滿足瀏覽器版本號的驅動下標matching_indices = []chromedriver_download_url = []try:h2_div_list = tree.xpath('.//h2[@class="h3"]/text()')for index,h2_item in enumerate(h2_div_list):chromedriver_version = h2_itemmatch_version = re.search(r'\((\d+\.\d+\.\d+\.\d+)\)', chromedriver_version)if match_version:chromedriver_version = match_version.group(1) # 獲取匹配到的版本號parts2 = chromedriver_version.split('.')# 比較前三個部分if parts1[:3] == parts2[:3]:matching_indices.append(index) # 如果滿足條件,將索引添加到結果列表中for index in matching_indices:chromedriver_table = tree.xpath('/html/body//div[@class="row"]//div[@class="manual-article"]/div[@class="article-content"]')[0]target_table = chromedriver_table.xpath(f'./table[{index+1}]')[0]chromedriver_tr_list = target_table.xpath('./tbody/tr')for chromedriver_tr in chromedriver_tr_list:if "chromedriver-win64.zip" in chromedriver_tr.xpath('.//text()')[5]:chromedriver_download_url.append(chromedriver_tr.xpath('.//text()')[5])return chromedriver_download_urlexcept Exception as e:print(f"程序發生了異常:{e}")return Noneelse:print("請求chromedriver下載鏈接頁失敗")
3、解壓到本地指定文件夾
def download_chromedriver(chromedriver_download_url,browser_version):if chromedriver_download_url:for url in chromedriver_download_url:# 指定保存壓縮文件的本地路徑zip_file_path = f"chromedriver{browser_version}-win64.zip"# 指定解壓后的文件夾路徑extract_folder_path = f"chromedriver{browser_version}"try:# 發起請求下載文件headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'}response = requests.get(url=url,headers=headers)response.raise_for_status() # 檢查請求是否成功# 將下載的文件寫入本地with open(zip_file_path, "wb") as file:file.write(response.content)# 創建解壓文件夾(如果不存在)if not os.path.exists(extract_folder_path):os.makedirs(extract_folder_path)# 解壓文件with zipfile.ZipFile(zip_file_path, "r") as zip_ref:zip_ref.extractall(extract_folder_path)# 獲取解壓文件夾的子文件夾subfolders = [f for f in os.listdir(extract_folder_path) ifos.path.isdir(os.path.join(extract_folder_path, f))]# 獲取子文件夾的路徑subfolder_path = os.path.join(extract_folder_path, subfolders[0])# 構造chromedriver.exe的絕對路徑chromedriver_path = os.path.join(subfolder_path, "chromedriver.exe")# 檢查chromedriver.exe文件是否存在if os.path.exists(chromedriver_path):print("chromedriver.exe的絕對路徑為:", chromedriver_path)else:print("子文件夾下沒有找到chromedriver.exe文件")print(f"文件已成功下載并解壓到 {extract_folder_path} 文件夾中,路徑為{chromedriver_path}。")break # 有一個壓縮包下載成功即跳出循環except requests.exceptions.RequestException as e:print(f"下載文件時出錯:{e}")print("請檢查網頁鏈接的合法性,適當重試。")except zipfile.BadZipFile:print("下載的文件不是有效的zip文件。")print("請檢查網頁鏈接的合法性,適當重試。")except Exception as e:print(f"發生錯誤:{e}")
之后將chromedriver_path寫入到項目的配置文件中,提供給使用selenium的腳本讀取。
3.2.2、方法二
使用webdriver_manager,它的核心功能是自動檢測已安裝的瀏覽器版本,并下載匹配的驅動程序。
1、安裝方法
pip install webdriver-manager
2、基本使用
from webdriver_manager.chrome import ChromeDriverManager# 安裝 ChromeDriver
driver_path = ChromeDriverManager().install()print(driver_path)
此時下載的瀏覽器驅動、下載位置均為默認,一般情況下直接在selenium創建driver對象時使用,但是會拖慢程序運行速度。
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver# 自動下載并配置ChromeDriver
driver = webdriver.Chrome(ChromeDriverManager().install())# 使用driver進行測試
driver.get("https://www.baidu.com/")
print(driver.title)
driver.quit()