今天帶大家一起學(xué)習(xí)下python爬蟲4小分隊(duì)(scrapy、beautifulsoup、selenium以及pyppeteer)之一的Selenium庫(kù),主要用于
模擬瀏覽器運(yùn)行,是一個(gè)用于web
應(yīng)用測(cè)試的工具。Selenium
直接運(yùn)行在瀏覽器中,看起來(lái)就像人在操作一樣(也可無(wú)窗口模式運(yùn)行)。支持的瀏覽器包括IE、
Firefox、
Safari、
Chrome、
Opera
和Edge
等。
下面主要以Chrome
為例進(jìn)行Selenium功能講解,但是會(huì)附帶其他瀏覽器的準(zhǔn)備講解。
0. 準(zhǔn)備工作
Python:3.9
selenium庫(kù):4.3.0
開發(fā)工具:PyCharm 2022.1.3
本文內(nèi)容會(huì)涉及python3、selenium4、javascript、html等內(nèi)容,需要有一定基礎(chǔ),或者有很強(qiáng)的的接受能力。
在學(xué)習(xí)之前,比較喜歡來(lái)個(gè)清晰的目錄,讓大家都有個(gè)整體的認(rèn)識(shí)先,下面是我整理的思維導(dǎo)圖,有需要高清圖的朋友可以私信。
后面我們就開始先安裝Chrome
瀏覽器(省略哈)并配置好ChromeDriver
,當(dāng)然也要安裝好selenium
庫(kù)!還有Python環(huán)境(也是省略,有需要的看下我其他關(guān)于安裝Python環(huán)境文章)。
寫在前面:出現(xiàn) DeprecationWarning 警告的類型錯(cuò)誤:該類型的警告大多屬于版本已經(jīng)更新,所使用的方法即將棄用。所以下面代碼為了讓讀者更快捷辨識(shí)兩個(gè)版本寫法,都已經(jīng)整理出來(lái),記得點(diǎn)個(gè)贊哦。
通過(guò)webdriver對(duì)象的find_element_by_xx(" ")(在selenium的4.0版本中此種用法即將棄用,不推薦使用),要使用通過(guò)webdriver模塊中的By,以指定方式定位元素。
1. 安裝selenium庫(kù)
pip install selenium
2. 安裝瀏覽器驅(qū)動(dòng)?
安裝驅(qū)動(dòng),咱們可以分為兩種方式去做,一種是手動(dòng)下載驅(qū)動(dòng)到本地,由項(xiàng)目直接調(diào)用,第二種就是通過(guò)第三方庫(kù)來(lái)自動(dòng)安裝,下面我們都詳細(xì)介紹兩種方式具體操作。
這里省略掉chrome或者其他瀏覽器的安裝過(guò)程,默認(rèn)大家都已經(jīng)安裝好心儀瀏覽器了~~~
2.1 手動(dòng)安裝驅(qū)動(dòng)
第一步:查看瀏覽器版本號(hào)
打開瀏覽器-說(shuō)明-關(guān)于Google Chrome,就可以看到我們的版本號(hào)了。
?第二步:根據(jù)版本號(hào)選擇合適的瀏覽器驅(qū)動(dòng)
ChromeDriver地址:https://registry.npmmirror.com/binary.html?path=chromedriver/
ChromeDrive國(guó)內(nèi)源:https://mirrors.huaweicloud.com/chromedriver/
最新chrome版本驅(qū)動(dòng)地址:Chrome for Testing availability
?
因?yàn)樽髡呤莣indows的所以就選了win版,只有32位是能夠兼容64位使用的,所以不用擔(dān)心有什么問(wèn)題。
第三步:下載驅(qū)動(dòng)到本地
將下載好的Driver文件放到項(xiàng)目目錄下,方便在使用的時(shí)候填寫路徑(如果不寫絕對(duì)路徑,就要將driver文件移到python的script目錄下)
path = r'D:\software\PyCharmLib\chromedriver.exe' # 驅(qū)動(dòng)文件存放的位置
# 如果存在DeprecationWarning警告,就需要使用新版本寫法
path = Service(r'D:\software\PyCharmLib\chromedriver.exe')
?具體用法下面再詳細(xì)說(shuō)明。
第四步:其他瀏覽器的Driver地址?
(IE瀏覽器)IEDriverServer地址:iedriverserver
(火狐瀏覽器)GeckoDriver地址:geckodriver
(safari瀏覽器)SafariDriver地址:驅(qū)動(dòng)已存在本地,路徑:/usr/bin/safaridriver
(opera瀏覽器)OperaDriver地址:operadriver
(edge瀏覽器)EdgeDriver地址:edgedriver
2.2 自動(dòng)安裝驅(qū)動(dòng)
要想實(shí)現(xiàn)自動(dòng)安裝瀏覽器驅(qū)動(dòng),我們就需要用到第三方庫(kù)?webdriver_manager?,直接下載該庫(kù)使用即可。
pip install webdrivermanager
如果是pycharm編輯器直接在項(xiàng)目里面添加:
?添加完,簡(jiǎn)單調(diào)用一下:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
# 新版本寫法
browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# 舊版寫法
# browser = webdriver.Chrome(ChromeDriverManager().install())
browser.get('http://www.baidu.com')
# 新版寫法
search = browser.find_element(By.ID, 'kw')
# 舊版寫法
# search = browser.find_element_by_id('kw')
search.send_keys('python')
search.send_keys(Keys.ENTER)
# 關(guān)閉瀏覽器
browser.close()
?上面代碼就是簡(jiǎn)單觸發(fā)了一下瀏覽器,主要是由ChromeDriverManager().install() 方法自動(dòng)安裝默認(rèn)瀏覽器的適配驅(qū)動(dòng),首先它會(huì)獲取當(dāng)前瀏覽器版本號(hào),再去下載相關(guān)驅(qū)動(dòng)。
注意:使用自動(dòng)下載親測(cè)每次啟動(dòng)都很慢,因?yàn)槊看味紩?huì)重新識(shí)別、調(diào)用,所以各位朋友慎用。
上面所有內(nèi)容就是我們初步需要準(zhǔn)備的基礎(chǔ)。
3. selenium基本用法
下面開始講初始化瀏覽器對(duì)象、訪問(wèn)頁(yè)面、設(shè)置瀏覽器大小、刷新頁(yè)面和前進(jìn)后退等基礎(chǔ)操作。
3.1 初始化瀏覽器對(duì)象
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
# 新版本寫法
browser = webdriver.Chrome(service=
Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 舊版寫法
# browser = webdriver.Chrome(r'D:\software\PyCharmLib\chromedriver.exe')
browser.get('http://www.baidu.com')
# 新版寫法
search = browser.find_element(By.ID, 'kw')
# 舊版寫法
# search = browser.find_element_by_id('kw')
search.send_keys('python')
search.send_keys(Keys.ENTER)
# 關(guān)閉瀏覽器
browser.close()
?通過(guò)上面代碼會(huì)打開我們的瀏覽器界面后并關(guān)閉:
一般采用最簡(jiǎn)單的瀏覽器初始化都是帶有界面的,但是我們還是設(shè)置成?無(wú)界面瀏覽器
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
# 設(shè)置無(wú)界面瀏覽器
option = webdriver.ChromeOptions() # 創(chuàng)建一個(gè)配置對(duì)象
option.add_argument("--headless") # 開啟無(wú)界面模式
option.add_argument("--disable-gpu") # 禁用gpu
# options.set_headles() # 無(wú)界面模式的另外一種開啟方式
# 實(shí)例化帶有配置的driver對(duì)象
browser = webdriver.Chrome(service=
Service(r'D:\software\PyCharmLib\chromedriver.exe'), options=option)
browser.get('http://www.baidu.com')
# 新版寫法
search = browser.find_element(By.ID, 'kw')
search.send_keys('python')
search.send_keys(Keys.ENTER)
# 關(guān)閉瀏覽器
browser.close()
?通過(guò)提前把參數(shù)準(zhǔn)備好,在初始化的時(shí)候設(shè)置進(jìn)去,這樣子瀏覽器就不會(huì)打開任何界面。
3.2 訪問(wèn)頁(yè)面
進(jìn)行頁(yè)面訪問(wèn)使用的是?get( url )?
方法,url就是待訪問(wèn)頁(yè)面的URL
地址參數(shù)。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 實(shí)例化帶有配置的driver對(duì)象
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)頁(yè)面
browser.get('http://www.baidu.com')
# 關(guān)閉瀏覽器
browser.close()
3.3 設(shè)置瀏覽器大小
通過(guò)
set_window_size()
方法就可以設(shè)置瀏覽器大小
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 實(shí)例化帶有配置的driver對(duì)象
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)頁(yè)面
browser.get('http://www.baidu.com')
# 設(shè)置瀏覽器大小為500*500像素
browser.set_window_size(500, 500)
# 關(guān)閉瀏覽器
# browser.close()
還可以通過(guò)?maximize_window() 方法設(shè)置瀏覽器全屏
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 實(shí)例化帶有配置的driver對(duì)象
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)頁(yè)面
browser.get('http://www.baidu.com')
# 設(shè)置瀏覽器全屏
browser.maximize_window()
# 關(guān)閉瀏覽器
# browser.close()
3.4 刷新頁(yè)面
refresh()
方法可以用來(lái)進(jìn)行瀏覽器頁(yè)面刷新,等同于我們平時(shí)用的F5按鍵,有些頁(yè)面需要定時(shí)刷新,這也算是比較常用方法。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time
# 實(shí)例化帶有配置的driver對(duì)象
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)頁(yè)面
browser.get('http://www.baidu.com')
time.sleep(1)
# 刷新瀏覽器
try:
browser.refresh()
print('刷新頁(yè)面成功')
except Exception as e:
print('刷新頁(yè)面失敗')
3.5 前進(jìn)后退
forward()
方法可以用來(lái)實(shí)現(xiàn)前進(jìn),back()
可以用來(lái)實(shí)現(xiàn)后退。下面我們來(lái)玩套組合拳。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time
# 實(shí)例化
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 打開百度頁(yè)面
browser.get('https://www.baidu.com')
time.sleep(1)
# 打開csdn網(wǎng)頁(yè)
browser.get('https://www.csdn.net/')
time.sleep(1)
# 后退回百度頁(yè)面
browser.back()
time.sleep(1)
# 前進(jìn)到csdn頁(yè)面
browser.forward()
這樣就能開始連續(xù)跳動(dòng)了,看起來(lái)就像人在操作一樣。
這里設(shè)置睡眠時(shí)間是為了大家更直觀看到效果,同時(shí)這個(gè)睡眠時(shí)間在實(shí)際應(yīng)用中是十分有用的,搭配隨機(jī)模塊?time.sleep(random.uniform(intx,inty))?,生成隨機(jī)睡眠時(shí)間能夠讓網(wǎng)站更難判斷出到底是不是自動(dòng)化機(jī)器在收集數(shù)據(jù),也算是?反屏蔽小手段?之一。
4. 獲取頁(yè)面基礎(chǔ)屬性
通過(guò)selenium打開網(wǎng)頁(yè)后,我們就能獲取到頁(yè)面的title標(biāo)題,current_url網(wǎng)頁(yè)地址,name瀏覽器名,page_source網(wǎng)頁(yè)源碼等內(nèi)容。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 實(shí)例化
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 瀏覽器標(biāo)題
title = browser.title
print(title)
# 瀏覽器地址
url = browser.current_url
print(url)
# 瀏覽器名
name = browser.name
print(name)
# 瀏覽器源碼
source = browser.page_source
print(source)
通過(guò)上面代碼訪問(wèn)CSDN首頁(yè),獲取到符合我們預(yù)期的屬性內(nèi)容。
其中獲取到源碼后,我們還可以通過(guò)正則、Xpath等方法對(duì)內(nèi)容進(jìn)行提取,但是個(gè)人建議用selenium做這個(gè)不太適合,還不如用beautifulsoup去實(shí)現(xiàn),效率和效果都更好。??
5. 定位頁(yè)面元素
這是個(gè)十分重要的知識(shí)點(diǎn),學(xué)的好不好決定了后面獲取頁(yè)面元素采集數(shù)據(jù)成功性。
5.1 ID定位 - find_element_by_id()
(id屬性值與位置匹配的第一個(gè)元素將被返回。)
find_element_by_id('xx') 能夠幫助我們獲取到id為xx的元素
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)id為toolbar-search-input的搜索框,并且輸入python
browser.find_element(By.ID, 'toolbar-search-input').send_keys('Python')
# selenium4.0前版本寫法
# browser.find_element_by_id('toolbar-search-input').send_keys('Python')
?通過(guò)ID定位方法,我們成功找到搜索框并輸入Pyhont內(nèi)容。
5.2 name定位 - find_element_by_name()
(名稱屬性值與位置匹配的第一個(gè)元素將被返回。)
find_element_by_name('xx') 能夠幫助我們獲取到name為xx的元素
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)百度首頁(yè)
browser.get('https://www.baidu.com/')
# 獲取百度首頁(yè)name為wd的搜索框,并且輸入python
browser.find_element(By.NAME, 'wd').send_keys('Python')
# selenium4.0前版本寫法
# browser.find_element_by_name('wd').send_keys('Python')
5.3 class定位 - find_element_by_class_name()
(具有匹配的類屬性名稱的第一個(gè)元素將被返回。)
通過(guò)find_element_by_class_name(‘xx’)方法就可以獲取到網(wǎng)頁(yè)中class名為xx的第一個(gè)元素。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)百度首頁(yè)
browser.get('https://www.baidu.com/')
# 獲取百度首頁(yè)classname為s_ipt的搜索框,并且輸入python
browser.find_element(By.CLASS_NAME, 's_ipt').send_keys('Python')
# selenium4.0前版本寫法
# browser.find_element_by_class_name('s_ipt').send_keys('Python')
5.4 tag定位 - find_element_by_tag_name()
(具有給定標(biāo)簽名稱的第一個(gè)元素將被返回。)
每個(gè)元素都有tag(標(biāo)簽)屬性,如搜索框的標(biāo)簽屬性,input
是輸入,table
是表格等等。我們查看百度首頁(yè)的html
代碼,可以看到有相同的Tag,很明顯相同的tag太多,一般很少用tag來(lái)做定位。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)tag為h3的文本內(nèi)容
h = browser.find_element(By.TAG_NAME, 'h3').text
print(h)
# selenium4.0前版本寫法
# browser.find_element_by_tag_name('h3').text
5.5 link定位 - find_element_by_link_text()
(鏈接文本值與位置匹配的第一個(gè)元素將被返回。)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)百度首頁(yè)
browser.get('https://www.baidu.com/')
# 獲取百度首頁(yè)link內(nèi)容為新聞的鏈接,并點(diǎn)擊
browser.find_element(By.LINK_TEXT, '新聞').click()
# selenium4.0前版本寫法
# browser.find_element_by_link_text('新聞').click()
獲取到百度首頁(yè)左上角的新聞鏈接并觸發(fā)點(diǎn)擊事件。
5.6 partial定位 - find_element_by_partial_link_text()
(具有部分鏈接文本值與位置匹配的第一個(gè)元素將被返回。)
相當(dāng)于link定位的模糊搜索方法,一般一個(gè)鏈接文本都很長(zhǎng),要是全部都輸入就太麻煩了,所以我們只需要輸入關(guān)鍵詞來(lái)進(jìn)行匹配即可。
?下面我們用csdn的首頁(yè)“下載·課程”來(lái)做示例,我們只需要定位“課程”,然后觸發(fā)點(diǎn)擊。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)link內(nèi)容為課程的模糊檢索鏈接,并點(diǎn)擊
browser.find_element(By.PARTIAL_LINK_TEXT, '課程').click()
# selenium4.0前版本寫法
# browser.find_element_by_partial_link_text('課程').click()
5.7 Xpath定位 - find_element_by_xpath()
(xpath語(yǔ)法與位置匹配的第一個(gè)元素將被返回。)
前面介紹的id定位、name定位、tap定位、link定位都是比較理想化的定位方式,對(duì)于簡(jiǎn)單的網(wǎng)站來(lái)說(shuō)使用起來(lái)效果不錯(cuò),前提是這些內(nèi)容都是唯一的,id唯一、name唯一、tap唯一、link內(nèi)容唯一等,但是對(duì)于大型網(wǎng)站來(lái)說(shuō),就顯得力不從心了,所以我們就要用更強(qiáng)大的定位工具xpath。
如果不太了解xpath語(yǔ)法的朋友可以先看下一文讀懂XPATH基本語(yǔ)法
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè),通過(guò)xpath檢索搜索框,并輸入python內(nèi)容
browser.find_element(
By.XPATH, "http://*[@id='toolbar-search-input']").send_keys('Python')
# selenium4.0前版本寫法
# browser.find_element_by_xpath(
# "http://*[@id='toolbar-search-input']").send_keys('Python')
5.8 CSS定位 - find_selement_by_css_selector()
(具有匹配的CSS選擇器的第一個(gè)元素將被返回。)
使用CSS定位方法會(huì)比xpath更加簡(jiǎn)潔,效率更高。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè),通過(guò)css寫法,獲取id為toolbar-search-input的搜索框
browser.find_element(By.CSS_SELECTOR, "#toolbar-search-input")\
.send_keys('Python')
# selenium4.0前版本寫法
# browser.find_element_by_css_selector('#toolbar-search-input')\
# .send_keys('Python')
5.9 By定位 - find_selement(By.XXX, 定位置)
前文也提到過(guò)在新版的selenium庫(kù)使用上述8種定位方法會(huì)出現(xiàn)警告,標(biāo)識(shí)上面語(yǔ)法即將被棄用,建議大家使用下面方法來(lái)替換。
首先引入By類:
from selenium.webdriver.common.by import By
上面一直使用都是By方式,同時(shí)也把即將棄用的方式寫在下方方便大家學(xué)習(xí)的時(shí)候進(jìn)行對(duì)比,咱這里就不再贅述了,還沒(méi)掌握的朋友可以多瀏覽上面的內(nèi)容。
5.10 文本定位 (和link不一樣)
有時(shí)還有些特殊的想法,能不能直接通過(guò)文本內(nèi)容去定位元素,但是這個(gè)元素又不是超鏈接a,此時(shí)可以通過(guò)下面的方法來(lái)定位元素
注意的是也是優(yōu)先捕捉第一個(gè)檢測(cè)到的元素,屬于模糊搜索
# 通過(guò)文本定位任意元素
browser.find_element(By.XPATH, "http://*[contains(text(), '你想要定位的文本內(nèi)容')]")
5.11 多元素?- find_selements()
如果在網(wǎng)站中定位的元素不止一個(gè),就需要用到find_elements()
,得到的結(jié)果會(huì)是列表形式。簡(jiǎn)單點(diǎn),就是element
后面多了s
,其他都一樣,下面舉一反三:
# 獲取id為id的第一個(gè)元素
find_selement_by_id('id').click()
# 獲取id為id的列表
find_selements_by_id('id')
# By寫法:
find_selement(By.ID, 'id').click()
find_selements(By.ID, 'id')
6 獲取元素屬性
通過(guò)第5點(diǎn)的定位方式,我們已經(jīng)基本掌握了全部定位方式,那么我就可以通過(guò)定位后來(lái)獲取定位元素的屬性了,在進(jìn)行Selenium數(shù)據(jù)收集/網(wǎng)絡(luò)爬蟲的時(shí)候,能讓我們更方便對(duì)內(nèi)容把控。
6.1 獲取屬性 - get_attribute()
下面我們來(lái)學(xué)習(xí)通過(guò)get_attribute()方法獲取csdn首頁(yè)的LOGO屬性。
?這里獲取比較復(fù)雜,但是這里也能更好鍛煉我們之前學(xué)過(guò)的XPath方法,當(dāng)然還有其他獲取的方式,歡迎各位朋友在評(píng)論區(qū)發(fā)表自己的看法。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)內(nèi)容
logo = browser.find_element(
By.XPATH, "http://div[@class='toolbar-logo toolbar-subMenu-box csdn-toolbar-fl']//img")
# 獲取圖片標(biāo)題
logo_title = logo.get_attribute('title')
print(logo_title)
# 獲取圖片路徑
logo_src = logo.get_attribute('src')
print(logo_src)
運(yùn)行代碼結(jié)果:這樣我們就能同時(shí)獲得logo的標(biāo)題和圖片地址
?6.2 獲取文本 - text
下面我們通過(guò)獲取CSDN首頁(yè)的頭條內(nèi)容標(biāo)題的文本,我們發(fā)現(xiàn)a標(biāo)簽其實(shí)內(nèi)容都一樣,只能通過(guò)父級(jí)div定位到a標(biāo)簽再獲取文本。
下面我們通過(guò)獲取CSDN首頁(yè)的頭條標(biāo)題來(lái)看下實(shí)際效果:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)內(nèi)容
txt = browser.find_element(
By.XPATH, "http://dd[@class='desc']//a").text
print(txt)
?運(yùn)行后的結(jié)果:
6.3 獲取其他屬性 - id、location、size、tag_name
除了文本常用之外,我們還需要關(guān)注下其他幾個(gè)常用屬性,例如id、locaition位置、size大小(圖片)、tag_name標(biāo)簽名等。
下面我們通過(guò)獲取CSDN首頁(yè)的頭條圖片來(lái)看下實(shí)際效果:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)內(nèi)容
hot_img = browser.find_element(
By.XPATH, "http://dt[@data-v-e8da5228]/a/img")
print(hot_img.text)
print(hot_img.id)
print(hot_img.location)
print(hot_img.tag_name)
print(hot_img.size)
運(yùn)行后的結(jié)果:因?yàn)闆](méi)有文本內(nèi)容text,所以第一行打印是空白的。?
?7 交互效果
?7.1 輸入文本 - send_keys()
在上面我們已經(jīng)使用過(guò)該函數(shù),一般在可輸入文本的地方使用。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)id為toolbar-search-input的搜索框,并且輸入python
browser.find_element(By.ID, 'toolbar-search-input').send_keys('Python')
7.2 點(diǎn)擊 - click()
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)百度首頁(yè)
browser.get('https://www.baidu.com/')
# 獲取百度首頁(yè)link內(nèi)容為新聞的鏈接,并點(diǎn)擊
browser.find_element(By.LINK_TEXT, '新聞').click()
7.3 清除文本 - clear()
既然有輸入,那就有清除。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)csdn首頁(yè)
browser.get('https://www.csdn.net/')
# 獲取csdn首頁(yè)id為toolbar-search-input的搜索框,并且輸入python
sea = browser.find_element(By.ID, 'toolbar-search-input')
# 輸入python
sea.send_keys('Python')
time.sleep(2)
# 清除文本
sea.clear()
7.4 回車確認(rèn) - submit()
實(shí)際效果就像表單提交一樣,例如我們?cè)谳斎肟蜉斎雙ython后,觸發(fā)submit就可以提交搜索了。
注意:并不是所有的輸入框都能觸發(fā),只有下方存在input type=submit情況下才能成功觸發(fā)。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 訪問(wèn)百度首頁(yè)
browser.get('https://www.baidu.com/')
time.sleep(1)
# 獲取百度首頁(yè)id為kw的搜索框,并且輸入python
inputs = browser.find_element(By.ID, 'kw')
inputs.send_keys('Python')
time.sleep(1)
# 搜索python
inputs.submit()
7.5 單選
單選沒(méi)有特定函數(shù),基本思路就是find_element()定位到需要單選的某個(gè)元素,然后click()點(diǎn)擊一下即可。
下面咱們就用上面學(xué)過(guò)的內(nèi)容來(lái)做一次聯(lián)合操作,來(lái)保存百度首頁(yè)的搜索設(shè)置:將“全部語(yǔ)言”改成“簡(jiǎn)體中文”。
代碼如下:
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
# 固定窗口大小,方便瀏覽
browser.set_window_size(1260, 925)
# 訪問(wèn)百度首頁(yè)
browser.get('https://www.baidu.com/')
time.sleep(1)
# 懸停操作
div_element = browser.find_element(By.ID, 's-usersetting-top')
ActionChains(browser).move_to_element(div_element).perform()
time.sleep(1)
# 獲取搜索設(shè)置按鈕,并點(diǎn)擊
browser.find_element(By.XPATH, '//div[@class="s-user-setting-pfmenu"]')\
.find_element(By.XPATH, '//a[1]/span').click()
time.sleep(1)
# 在設(shè)置中將語(yǔ)言范圍設(shè)置為僅簡(jiǎn)體中文
browser.find_element(By.ID, 'SL_1').click()
time.sleep(1)
# 保存設(shè)置
browser.find_element(By.XPATH, '//div[@id="se-setting-7"]/a[2]').click()
time.sleep(1)
# 關(guān)閉確認(rèn)窗口
alert = browser.switch_to.alert
alert.accept()
上面都有注釋,就不再累述了。除了 確認(rèn)Alert窗口 之外其他上面都已經(jīng)學(xué)過(guò)了。
7.6 多選
多選一樣沒(méi)有特定的函數(shù),方法也跟單選一樣是先定位在點(diǎn)擊,只是多選可以遍歷操作。這里也不再舉例子說(shuō)明了,大家舉一反三親自動(dòng)手試試。
7.7 下拉框 - Select
想操作下拉框,我們就需要借助 Select 模塊幫忙了。先導(dǎo)入該模塊:
from selenium.webdriver.support.select import Select
?然后我們?cè)賮?lái)總結(jié)下Select模塊給咱們帶來(lái)的新操作:
1、定位選擇框的方法:
select_by_index()? ? ? ? ? ? ? ? ? ? ? ? # 通過(guò)索引定位,index從0開始算
select_by_value()? ? ? ? ? ? ? ? ? ? ? ? # 通過(guò)option中value屬性的值來(lái)定位
select_by_visible_text()? ? ? ? ? ? ? ?# 通過(guò)文本值定位,即下拉框的值
2、獲取基本信息
voptions? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 返回select元素所有options
all_selected_options? ? ? ? ? ? ? ? ? ? # 返回select元素中已選的所有options
first_selected_options? ? ? ? ? ? ? ? ? # 返回select元素中已選的第一個(gè)options
3、取消已選中項(xiàng)的方法:
deselect_all()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 取消已選中的所有項(xiàng)
deselect_by_index()? ? ? ? ? ? ? ? ? ? # 取消已選中的等于index索引的項(xiàng)
deselect_by_value()? ? ? ? ? ? ? ? ? ? # 取消已選中的等于value值的項(xiàng)
deselect_by_visible_text()? ? ? ? ? ?# 取消已選中的等于文本值的項(xiàng)
下面咱們來(lái)實(shí)戰(zhàn),就會(huì)更容易明白各個(gè)方法和屬性的作用和效果,由于臨時(shí)找不到合適的教材,咱們直接準(zhǔn)備了一個(gè)html案例,fruit.html,代碼如下:?
<!DOCTYPE html>
<html>
<head>
<title>selenium select test</title>
</head>
<body>
<form>
<label>選擇水果:</label>
<select name="fruit">
<option value="apple">蘋果</option>
<option value="pear">梨</option>
<option value="banana">香蕉</option>
<option value="watermelon">西瓜</option>
</select>
</form>
</body>
</html>
然后就是我們通過(guò) Select模塊 操作下拉框的代碼
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
# 初始化瀏覽器,并打開本地文件
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
browser.get('file://C:/Users/root/Desktop/fruit.html')
time.sleep(1)
# 選中下拉框元素
sel = Select(browser.find_element(By.NAME, 'fruit'))
num = 0
for i in sel.options:
num = num+1
print('選項(xiàng)%d:%s'%(num, i.text))
# 通過(guò)index定位
sel.select_by_index(1)
print('第一個(gè)選中項(xiàng):%s'%(sel.first_selected_option.text))
time.sleep(2)
# 通過(guò)value定位
sel.select_by_value('banana')
for j in sel.all_selected_options:
print('全部選中項(xiàng):%s'%j.text)
time.sleep(2)
# 通過(guò)文本定位
sel.select_by_visible_text('西瓜')
time.sleep(2)
?下面就是我們的運(yùn)行結(jié)果:
?基本上對(duì)于元素的處理基本就到這里了,后面還有關(guān)于元素屬性的增刪改操作。
8 處理彈窗
通過(guò)上面7.5單選的示例代碼在運(yùn)行的時(shí)候就會(huì)碰到有alert彈窗提示,下面我們就詳細(xì)介紹alert提示彈窗、確認(rèn)confirm彈窗、輸入內(nèi)容prompt彈窗。順便說(shuō)下核心方法主要有:
text()? ? ? ? ? ? ? ? ?# 獲取文本值
accept()? ? ? ? ? ? # 點(diǎn)擊“確認(rèn)”
dismiss()? ? ? ? ? ?# 點(diǎn)擊“取消”或者是關(guān)閉叉掉對(duì)話框
send_keys()? ? ? #?輸入文本值 ,僅限于prompt,在alert和confirm上沒(méi)有輸入框
下面直接上示例,在我們本地運(yùn)行?alert.html ,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>selenium alert</title>
</head>
<body>
<a href="javascript:alert('提示框')" id="alert">
test_Alert
</a>
<br>
<a href="javascript:confirm('確認(rèn)框,如:真的要?jiǎng)h除嗎?')" id="confirm">
test_Confirm
</a>
<br>
<a href="javascript:var why = prompt('輸入內(nèi)容框,如:請(qǐng)輸入內(nèi)容?');document.write(why) " id="prompt">
test_Prompt
</a>
<br>
</body>
</html>
然后,我們對(duì)不同彈窗間的處理:
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# 初始化瀏覽器,并打開本地文件
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'))
browser.get('file://C:/Users/root/Desktop/alert.html')
time.sleep(1)
# 用于提示
def test_alert():
# 定位元素
browser.find_element(By.ID, 'alert').click()
# 切換到alert
alert = browser.switch_to.alert
print(alert.text) # 打印alert內(nèi)容
time.sleep(3)
alert.accept() # 相當(dāng)于點(diǎn)擊確認(rèn)按鈕
# 用于確認(rèn)
def test_confirm():
# 定位元素
browser.find_element(By.ID, 'confirm').click()
# 切換到alert
confirm = browser.switch_to.alert
# 打印alert內(nèi)容
print(confirm.text)
time.sleep(3)
# 相當(dāng)于點(diǎn)擊確認(rèn)按鈕
confirm.accept()
# 相當(dāng)于點(diǎn)擊取消按鈕
# confirm.dismiss()
# 用于輸入內(nèi)容
def test_prompt():
# 定位元素
browser.find_element(By.ID, 'prompt').click()
# 切換到alert
prompt = browser.switch_to.alert
print(prompt.text) # 打印alert內(nèi)容
# 輸入文本
prompt.send_keys('記得點(diǎn)個(gè)贊!?。?)
time.sleep(3)
prompt.accept() # 相當(dāng)于點(diǎn)擊確認(rèn)按鈕
time.sleep(3)
# confirm.dismiss() # 相當(dāng)于點(diǎn)擊取消按鈕
test_alert()
test_confirm()
test_prompt()
9 窗口切換
當(dāng)我們實(shí)際應(yīng)用之中很容易因?yàn)榫W(wǎng)站的流程或者我們爬取的業(yè)務(wù)過(guò)程中產(chǎn)生很多的窗口,這時(shí)候我們要切換窗口進(jìn)行操作,所以下面講解下同一頁(yè)面不同子頁(yè)面的切換、同一瀏覽器不同選項(xiàng)卡窗口的切換。
9.1 父子頁(yè)面切換
switch_to.frame()? ? ? ? ? ? ? ? ?# 切換同一頁(yè)面的不同子頁(yè)面
switch_to.parent_frame()? ? ?# 切換回父頁(yè)面
9.2 選項(xiàng)卡窗口切換
新建標(biāo)簽頁(yè):browser.execute_script('window.open("url","_blank");')
關(guān)閉標(biāo)簽頁(yè):browser.close()
切換標(biāo)簽頁(yè):browser.switch_to.window()
顯示全部標(biāo)簽頁(yè):browser.window_handles(返回當(dāng)前瀏覽器的所有窗口的句柄)
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
options = Options()
options.add_argument('--disable-gpu')
options.add_argument('lang=zh_CN.UTF-8')
# 初始化瀏覽器,并打開百度
browser = webdriver.Chrome(
service=Service(r'D:\software\PyCharmLib\chromedriver.exe'),
options=options)
browser.get('https://www.baidu.com')
time.sleep(1)
# 創(chuàng)建新標(biāo)簽頁(yè),打開csdn
browser.execute_script('window.open("https://csdn.net","_blank");')
print(browser.window_handles)
time.sleep(3)
# 切換回百度首頁(yè)
browser.switch_to.window(browser.window_handles[0])
time.sleep(2)
# 再切換回csdn首頁(yè)
browser.switch_to.window(browser.window_handles[-1])
time.sleep(2)
# 關(guān)閉當(dāng)前頁(yè)面,此時(shí)window的句柄還在csdn首頁(yè)
browser.close()
# 切換回csdn首頁(yè),這時(shí)句柄才是百度頁(yè)面
browser.switch_to.window(browser.window_handles[0])
10 模擬鼠標(biāo)操作
上面所有內(nèi)容都是講如何模擬瀏覽器操作的,當(dāng)然我們有時(shí)也要模擬鼠標(biāo)和鍵盤的操作,這里就先講模擬鼠標(biāo)操作。通過(guò)ActionChains模塊即可實(shí)現(xiàn)鼠標(biāo)左鍵點(diǎn)擊、右鍵點(diǎn)擊、雙擊、拖拽、懸停等。
from selenium.webdriver.common.action_chains import ActionChains
由于部分內(nèi)容重復(fù)出現(xiàn),所以下面代碼就只顯示核心部分+注釋說(shuō)明。?
10.1 左鍵點(diǎn)擊 - click()
其實(shí)就是我們上面經(jīng)常用到的click()函數(shù),這里就不累贅了。
10.2 右鍵點(diǎn)擊 - context_click()
# ActionChains(browser)將browser作為參數(shù)傳入ActionChains類中調(diào)用
# context_click(元素)對(duì)相應(yīng)元素鼠標(biāo)右鍵操作
# perform()類似于動(dòng)作的提前準(zhǔn)備
ActionChains(browser).context_click(元素).perform()
10.3 雙擊 - double_click()
ActionChains(browser).double_click(元素).perform()
10.4 懸停 - move_to_element()
ActionChains(browser).move_to_element(元素).perform()
10.5 拖拽 - drag_and_drop()
這是一個(gè)可以幫助我們處理滑動(dòng)驗(yàn)證碼的好方法,但是這里并不打算重點(diǎn)講這部分內(nèi)容,有興趣的可以看看我其他文章如何實(shí)現(xiàn)的。
ActionChains(browser).drag_and_drop(被拖元素,被拽到的元素).perform()
10.6 定位移動(dòng) -??move_by_offset()
通過(guò)拖拽可以處理好驗(yàn)證碼,但是對(duì)于視頻的控件有時(shí)不太理想,例如進(jìn)度,這時(shí)候就需要我們計(jì)算定位進(jìn)行點(diǎn)擊。重點(diǎn):move_by_offset()中使用坐標(biāo)都是針對(duì)上一步的計(jì)算的,若不想計(jì)算,可使用reset_actions() 重置為(0,0)
# 當(dāng)執(zhí)行reset_actions后,x和y就是按瀏覽器左上角位置計(jì)算
# 不執(zhí)行reset_actions,并且有其他動(dòng)作時(shí),以當(dāng)前位置增加x和y的量計(jì)算位置
ActionChains(driver).move_by_offset(x, y).click().perform()
# 重置定位
action.reset_actions()
如果不注意位置的計(jì)算,很容易遇到報(bào)錯(cuò):move target out of bounds !?
11 模擬鍵盤操作
既然有模擬鼠標(biāo)操作,就會(huì)有模擬鍵盤操作了,但是使用的模塊不一樣,這次模擬鍵盤操作用的是Keys()模塊,然后再通過(guò)send_keys()、key_down()、key_up()等函數(shù)搭配使用。
from selenium.webdriver.common.keys import Keys
?11.1 常用的鍵盤按鈕
Keys.BACK_SPACE? ? ? ? ? ? ? ? ?# 刪除鍵
Keys.SPACE? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 空格
Keys.TAB? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 制表鍵
Keys.ESCAPE? ? ? ? ? ? ? ? ? ? ? ? ? # 回退鍵
Keys.ENTER? ? ? ? ? ? ? ? ? ? ? ? ? ? # 回車鍵
Keys.ALT? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # alt鍵
Keys.CONTROL? ? ? ? ? ? ? ? ? ? ? ?# ctrl鍵
Keys.SHIRT? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # shirt鍵
Keys.F1...Keys.F12? ? ? ? ? ? ? ? ? # f1到f12鍵
11.2 常用組合按鍵
send_keys(Keys.CONTROL, 'a')? ? ? ? ?# 全選,ctrl+a
send_keys(Keys.CONTROL, 'x')? ? ? ? ?# 裁剪,ctrl+x
send_keys(Keys.CONTROL, 'c')? ? ? ? ?# 復(fù)制,ctrl+c
send_keys(Keys.CONTROL, 'v')? ? ? ? ?# 粘貼,ctrl+v
?敲黑板:如果使用上面方法沒(méi)有效果的話,建議使用下面寫法,完全模擬真實(shí)操作。
(類似平時(shí)先按住ctrl鍵,再松開)
ActionChains(driver).key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL)
.perform()
12 加載等待
在做數(shù)據(jù)收集(python爬蟲)的時(shí)候,每個(gè)網(wǎng)站打開后加載內(nèi)容的時(shí)間都不是固定的,一旦我們?cè)谠匚醇虞d出來(lái)前就操作,就會(huì)報(bào)錯(cuò):找不到相應(yīng)元素。那這時(shí)候我們就可以引入我們等待加載的技術(shù)了,平時(shí)測(cè)試的時(shí)候可以用 time.sleep()來(lái)強(qiáng)制固定時(shí)間等待,生產(chǎn)環(huán)境下就需要用更高級(jí)點(diǎn)的implicitly_wait()來(lái)固定時(shí)間等待頁(yè)面元素全部加載完成,最推薦的還是使用WebDriverWait特定條件加固定時(shí)間來(lái)判斷等待的結(jié)果。
12.1 強(qiáng)制等待
在driver.get(url)執(zhí)行后觸發(fā)即可,也可在其他操作后設(shè)置等待,防止報(bào)錯(cuò),使用time.sleep()控制。
12.2 implicitly_wait()等待
# 等待頁(yè)面元素全部加載出來(lái),時(shí)間為5秒
driver.implicitly_wait(5)
12.3 WebDriverWait等待【推薦】
在這里我們需要用到WebDriverWait模塊,以及EC模塊。
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
?WebDriverWait()的用法說(shuō)明:
webwait = WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
- driver:瀏覽器驅(qū)動(dòng)
- timeout:超時(shí)時(shí)間,秒
- poll_frequency:檢測(cè)頻率,默認(rèn)是0.5秒一次
- ignored_exceptions:超時(shí)后的報(bào)錯(cuò)信息,默認(rèn)是
NoSuchElementException異常
?WebDriverWait().until()的用法說(shuō)明:
當(dāng)某元素出現(xiàn)或什么條件成立則繼續(xù)執(zhí)行
webwait.until(method,msg='')
- method:在等待期間,每隔一段時(shí)間調(diào)用這個(gè)傳入的方法,直到返回值不是False
- msg:如果超時(shí),拋出
TimeoutException
,將msg
傳入異常
??WebDriverWait().until_not()的用法說(shuō)明:
當(dāng)某元素消失或什么條件不成立則繼續(xù)執(zhí)行,與until()相反。
webwait.until_not(method,msg='')
?使用參考示例:
webwait = WebDriverWait(browser, 6)
c = webwait.until(EC.presence_of_element_located((By.ID, 'ym')))
c.click()
13 補(bǔ)充內(nèi)容
13.1 Javascript調(diào)用
這里簡(jiǎn)單列出幾個(gè)常用的,有興趣的可以自行看下javascript的用法。
# 下拉滾動(dòng)條
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
# 彈出提示框
driver.execute_script('alert("到底了。")')
# 修改元素屬性
driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", 元素, 屬性名, 屬性值)
13.2?Cookie調(diào)用
# 添加cookie
browser.add_cookie(cookie_dict=)
# 獲取某個(gè)cookie
browser.get_cookie(name=)
# 獲取全部cookie
browser.get_cookies()
# 刪除某個(gè)cookie
browser.delete_cookie(name=)
# 刪除全部cookie
browser.delete_all_cookies()
13.3 反屏蔽
一般來(lái)講,使用selenium訪問(wèn)某個(gè)網(wǎng)址(瀏覽器以Chrome為例),都會(huì)有Chrome正受到自動(dòng)測(cè)試軟件的控制
的提示
檢測(cè)的基本原理:
檢測(cè)當(dāng)前瀏覽器窗口下的window.navigator對(duì)象是否包含webdriver這個(gè)屬性。因?yàn)樵谡J褂脼g覽器的情況下,這個(gè)屬性是undefined的,然而,一旦我們使用了selenium,selenium會(huì)給Window.navigator設(shè)置webdriver屬性,很多網(wǎng)站就通過(guò)JavaScript判斷,如果webdriver存在就直接屏蔽。
解決方法一:修改window.navigator.webdriver
關(guān)鍵字返回結(jié)果
def chrome_driver():
option = webdriver.ChromeOptions()
# 無(wú)頭模式,隱藏運(yùn)行
option.add_argument('--headless')
# 沙盒模式
option.add_argument('--no-sandbox')
# 禁用gpu加速(過(guò)慢時(shí)可考慮移除此項(xiàng))
option.add_argument('--disable-gpu')
option.add_argument('--disable-dev-shm-usage')
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
drivers = webdriver.Chrome(options=option)
drivers.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get:()=>undefined})'
})
return drivers
driver = chrome_driver()
driver.get('https://baidu.com')
此方法有效性比較局限。
?解決方法二:?使用stealth.min.js文件
stealth.min.js文件下載:點(diǎn)擊下載-CSDN
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument("--headless")
# driverurl自行替換瀏覽器驅(qū)動(dòng)
driver = Chrome(service='driverurl', options=options)
with open('/stealth.min.js') as f:
js = f.read()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": js
})
解決方法三:?undetected_chromedriver
undetected_chromedriver的源碼地址
可自動(dòng)下載瀏覽器驅(qū)動(dòng),可以防止瀏覽器特征被識(shí)別,基本可以解決selenium被識(shí)別的問(wèn)題。
import undetected_chromedriver as uc
driver = uc.Chrome()
driver.get('https://nowsecure.nl')
13.4 控制加載內(nèi)容,提升速度
在實(shí)際使用中,如果使用瀏覽器的“檢查”功能進(jìn)行網(wǎng)頁(yè)的逆向工程不是很復(fù)雜,就最好使用瀏覽器的“檢查”功能。不過(guò),也有些方法可以用Selenium控制瀏覽器加載的內(nèi)容,從而加快Selenium的爬取速度。
13.4.1 控制CSS加載
# 控制 css
from selenium import webdriver
fp = webdriver.FirefoxProfile()
fp.set_preference("permissions.default.stylesheet",2)
driver = webdriver.Firefox(firefox_profile=fp,
executable_path = r'C:\Users\santostang\Desktop\geckodriver.exe')
# 把上述地址改成你電腦中g(shù)eckodriver.exe程序的地址
driver.get("http://www.santostang.com/2018/07/04/hello-world/")
13.4.2 控制圖片加載
# 限制圖片的加載
from selenium import webdriver
fp = webdriver.FirefoxProfile()
fp.set_preference("permissions.default.image", 2)
driver = webdriver.Firefox(firefox_profile=fp,
executable_path=r'C:\Users\santostang\Desktop\geckodriver.exe')
# 把上述地址改成你電腦中g(shù)eckodriver.exe程序的地址
driver.get("https://www.santostang.com/2018/07/04/hello-world/")
# 【Chrome瀏覽器】
# 瀏覽器禁止加載圖片和css (這樣可以提升速度,不過(guò)要注意禁用css要在無(wú)操作的前提下,若有點(diǎn)擊、拖動(dòng)之類的可能會(huì)出錯(cuò))
# prefs = {"profile.managed_default_content_settings.images": 0, 'permissions.default.stylesheet': 0} # 不禁止加載圖片和css --> 這里會(huì)修改Chrome原始文件(如果同時(shí)調(diào)用chrome本地配置文件)
prefs = {"profile.managed_default_content_settings.images": 2, 'permissions.default.stylesheet': 2} # 只能用2,用False不行
option.add_experimental_option("prefs", prefs)
# 注意--》同時(shí)使用本地配置文件(免登陸)和禁用圖片,這里會(huì)對(duì)原始文件進(jìn)行修改,瀏覽器地址欄會(huì)出現(xiàn)圖片禁用圖標(biāo),此時(shí)無(wú)法在瀏覽器直接設(shè)置修改禁用圖片的操作,只能修改原始文件才行。(本人重裝chrome后才發(fā)現(xiàn))
13.4.3? 控制js的運(yùn)行
# 限制JavaScript的執(zhí)行
from selenium import webdriver
fp = webdriver.FirefoxProfile()
fp.set_preference("javascript.enabled", False)
driver = webdriver.Firefox(firefox_profile=fp,
executable_path=r'C:\Users\santostang\Desktop\geckodriver.exe')
# 把上述地址改成你電腦中g(shù)eckodriver.exe程序的地址
driver.get("http://www.santostang.com/2018/07/04/hello-world/")
13.5 options配置
參考文獻(xiàn):請(qǐng)點(diǎn)擊
options.add_argument(‘headless’) # 無(wú)頭模式
options.add_argument(‘window-size={}x{}’.format(width, height)) # 直接配置大小和set_window_size一樣
options.add_argument(‘disable-gpu’) # 禁用GPU加速
options.add_argument(‘proxy-server={}’.format(self.proxy_server)) # 配置代理
options.add_argument(’–no-sandbox’) # 沙盒模式運(yùn)行
options.add_argument(’–disable-setuid-sandbox’) # 禁用沙盒
options.add_argument(’–disable-dev-shm-usage’) # 大量渲染時(shí)候?qū)懭?tmp而非/dev/shm
options.add_argument(’–user-data-dir={profile_path}’.format(profile_path)) # 用戶數(shù)據(jù)存入指定文件
options.add_argument('no-default-browser-check) # 不做瀏覽器默認(rèn)檢查
options.add_argument("–disable-popup-blocking") # 允許彈窗
options.add_argument("–disable-extensions") # 禁用擴(kuò)展
options.add_argument("–ignore-certificate-errors") # 忽略不信任證書
options.add_argument("–no-first-run") # 初始化時(shí)為空白頁(yè)面
options.add_argument(’–start-maximized’) # 最大化啟動(dòng)
options.add_argument(’–disable-notifications’) # 禁用通知警告
options.add_argument(’–enable-automation’) # 通知(通知用戶其瀏覽器正由自動(dòng)化測(cè)試控制)
options.add_argument(’–disable-xss-auditor’) # 禁止xss防護(hù)
options.add_argument(’–disable-web-security’) # 關(guān)閉安全策略
options.add_argument(’–allow-running-insecure-content’) # 允許運(yùn)行不安全的內(nèi)容
options.add_argument(’–disable-webgl’) # 禁用webgl
options.add_argument(’–homedir={}’) # 指定主目錄存放位置
options.add_argument(’–disk-cache-dir={臨時(shí)文件目錄}’) # 指定臨時(shí)文件目錄
options.add_argument(‘disable-cache’) # 禁用緩存
options.add_argument(‘excludeSwitches’, [‘enable-automation’]) # 開發(fā)者模式option.add_argument('--disable-blink-features=AutomationControlled') # 規(guī)避檢測(cè)
14 寫在最后
在此感謝提供學(xué)習(xí)教材的網(wǎng)站。
CSDN首頁(yè):CSDN - 專業(yè)開發(fā)者社區(qū)
百度首頁(yè):百度一下,你就知道文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-675525.html
技術(shù)本無(wú)罪,請(qǐng)把爬蟲用在正途之上。?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-675525.html
到了這里,關(guān)于萬(wàn)字攻略全面了解selenium_selenium教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!