一、介紹selenium爬蟲工具
selenium 是一個自動化測試工具,可以用來進行 web 自動化測試、爬蟲
selenium 本質是通過驅動瀏覽器,完全模擬瀏覽器的操作,比如跳轉、輸入、點擊、下拉等,來拿到網頁渲染之后的結果,可支持多種瀏覽器
相對于普通的爬蟲工具:request、scrapy,selenium了解決它們無法直接執行 JavaScript 代碼等問題
下面就來介紹下 selenium 基礎用法
二、前期安裝配置工作
1、下載瀏覽器驅動器的網址
#Firefox瀏覽器驅動: https://github.com/mozilla/geckodriver/releases#Chrome瀏覽器驅動: #【114版本之前的】 https://registry.npmmirror.com/binary.html?path=chromedriver/ #【115版本之后的】 https://googlechromelabs.github.io/chrome-for-testing/#IE瀏覽器驅動:IEDriverServer https://selenium-release.storage.googleapis.com/index.html#Edge瀏覽器驅動:MicrosoftWebDriver https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver?form=MA13LH
2、例子:
【谷歌瀏覽器】
1、查找瀏覽器版本
;
2、我的是115版本以上的,所以對應到谷歌第二個驅動器安裝網站
找到對應的版本,然后復制跳轉它給的網址鏈接,就能自動下載了
【Microsoft Edge】
這個瀏覽器不需要看版本,直接進入驅動器安裝網址之后,點下面圖片的位置即可
3、配置瀏覽器驅動器
安裝完成之后我們要解壓壓縮包才能用
第一種配置,這里我們可以直接解壓到python編譯器的安裝主目錄下(不推薦,寫代碼麻煩)
記得是把含有exe程序的那一層根目錄解壓下來,別多套一層目錄了
第二種配置,我們可以直接配到系統環境變量里,全局使用(推薦,寫代碼方便)
往path里添加你驅動器的【根目錄】
測試【谷歌驅動器】的命令是
chromedriver --version #或者 chromedriver -v
;
測試【Edge驅動器】的命令是
msedgedriver --version #或者 msedgedriver -v
4、安裝
打開Python編譯器的命令行程序,運行下面 pip 命令::
pip install selenium
如果安裝不了,可能是網絡問題,可以指定使用國內的清華大學源
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
三、 啟用瀏覽器驅動器打開網站
現在配置完畢,我們就可以寫代碼來試一下啟動了
1、創建驅動器其對象
首先seleium的導入頭文件
from selenium import webdriver
如果你沒有配置系統變量,只是單純解壓了,那么你在寫代碼時創建瀏覽器驅動器,就需要手動導入你驅動器的exe程序文件的路徑
;
用【webdriver.瀏覽器()】方法來創建驅動器的對象,然后假如參數【service=Service(去驅動器exe的路徑)】(Service對象需要導入頭文件)
from selenium import webdriver from selenium.webdriver.chrome.service import Service# 如果只是解壓了驅動器,那么這里要啟動驅動器就得手動把各個驅動器的.exe文件的路徑,寫到Service參數里 # 谷歌瀏覽器的驅動器對象 ChromeDriver = webdriver.Chrome(service=Service(r'F:\python\chromedriver-win64\chromedriver.exe')) # Edge瀏覽器的驅動器對象 EdgeDriver = webdriver.Edge(service=Service(r'F:\python\edgedriver_win64\msedgedriver.exe'))
如果你已經配置好系統變量,檢查無誤,那么就可以直接用【webdriver.瀏覽器()】方法來創建驅動器的對象
from selenium import webdriver# 如果驅動器已經注冊到環境變量Path里了,那么就不需要寫路徑了,selenium會自動全局找到驅動器的位置 # 谷歌瀏覽器的驅動器對象 ChromeDriver = webdriver.Chrome() # Edge瀏覽器的驅動器對象 EdgeDriver = webdriver.Edge()
2、用驅動器打開一個網址
【驅動器對象.get( 網址 )】就能打開一個瀏覽器并進入到這個網址頁面了
不過注意,用一個瀏覽器的驅動器打開就行,別一次性用多種瀏覽器打開
還有,selenium默認執行完腳本就自動結束,就會馬上關閉瀏覽器,想要打開瀏覽器之后先留住,那就在最后隨便一個代碼,然后打個斷點,用【調試】來運行程序。用【運行】的話就一次性運行結束腳本了。
from selenium import webdriver# 創建驅動器對象
ChromeDriver = webdriver.Chrome()# 用【驅動器對象 .get()】打開網站
ChromeDriver.get('https://www.baidu.com')# pass是一個沒用的代碼,當你不知道寫什么就可以塞一個pass,比如循環體里加pass就是啥也不做,純循環
# 在這打個斷點,然后調試
pass
四、基礎操作
這里會涉及到http的知識點和HTML、CSS的知識點,我就不細講了,因為我覺得學計算機的應該都會
那么學過爬蟲的應該知道,網頁的結構就是HTML網頁代碼,我們要獲取的就是HTML的代碼里的元素
1、最基礎的用dom元素、id、class獲取元素
這些步驟應該不用我說了,檢查網頁元素,右鍵檢查或者F12,然后選擇元素,就能看到這個元素的HTML的代碼
那么標簽名、id選擇器、class選擇器我也懶得講了,不會的自己上網查,是最基礎的web前端開發基礎,當我們找到了我們要的某一個元素,并且看到了他的“標簽名、id名、class名”之后,我們就可以到代碼里定位這個元素了:
首先獲取單獨一個元素就是:【驅動器對象.find_element( )】
當你已知一個元素的某個標簽名、id名、class名,然后用這個方法能獲得這種元素的第一個
;
獲取同名的所有元素是:【驅動器對象.find_elements( )】
當你已知一個元素的某個標簽名、id名、class名,然后用這個方法能獲得所有叫這名的元素
不管是【驅動器對象.find_element( )】還是【驅動器對象.find_elements( )】都需要2個參數:
- 第一個是【通過標簽名、id選擇器、class選擇器】哪一個方式來選擇元素
- 需要用By這個對象,需要另外導入By的頭文件
- 通過標簽名就是:By.TAG_NAME
- 通過id名就是:By.ID
- 通過類名就是:By.CLASS_NAME
- 第二個是就是具體的【標簽名、id名、class名】,直接寫名字
例子:
from selenium.webdriver.common.by import By #By對象的頭文件# 根據標簽名獲取div的第一個元素(很少用!!!) divElement = ChromeDriver.find_element(By.TAG_NAME, 'div') # 根據id名獲取id叫“kw”的第一個元素(就是輸入框) inputElement = ChromeDriver.find_element(By.ID, 'kw') # 根據id名獲取id叫“su”的第一個元素(就是回車按鈕) enterButton = ChromeDriver.find_element(By.ID, 'su')# 根據類名叫“title-content-title”獲取所有這樣的元素 titleList = ChromeDriver.find_elements(By.CLASS_NAME, 'title-content-title')
2、獲取元素文字、屬性、html結構
1)標簽結構內的文字
前面我們已經獲取簡單的元素了,然后我們現在需要獲取里面的文字,這才是我們要的東西
很簡單 ————【元素對象.text】
element = ChromeDriver.find_element(By.CLASS_NAME, 'mnav') print(enterButton.text)
注意class=“類名1 類名2 ......”類名是可以用空格帶多個類名的,每一個類名都可以作為這個元素的類名
【提示】
如果【元素.text】沒有獲取到文字,還可以試一下【元素.innerText】或【元素.textContent】
2)元素的屬性
但是我們會發現有的元素的文字并不是在它的標簽結構里的:<標簽>文字</標簽>,而是嵌在元素里的:<標簽 target="文字" xxx="文字" value="文字" ...></標簽>
那么在標簽里的這些就是【屬性】了,用 ———【元素對象.get_attribute( '屬性名' ))】可獲取
enterButton = ChromeDriver.find_element(By.CLASS_NAME, 's_btn') print(enterButton.get_attribute('value'))
3)元素的HTML代碼
那么有的時候我們想看看這個元素是不是我要的,可以看一下他的HTML結構——【元素對象.outHTML】
enterButton = ChromeDriver.find_element(By.CLASS_NAME, 's_btn') print(enterButton.get_attribute('outerHTML'))
五、創建驅動器對象時優化處理問題
為了加快我們爬蟲程序的速度,我們需要在創建驅動器的時候,加入下面的寫法來優化我們的程序
1、頁面加載慢用【隱式等待】
隱式等待又叫全局等待
有的時候我們獲取元素明明代碼是對的,但是就是返回找不到......???
那這個時候就可能因為頁面加載太慢了,一個頁面加載需要發送請求到服務器、后端,還要操作瀏覽器驅動器,然而我們的程序是以極快的速度來執行腳本代碼的,當頁面還在加載的時候,程序可能已經開始執行【查找元素】的代碼了,那這個時候頁面啥也沒有那肯定就啥也找不到啊
那么selenium的解決辦法就是用【隱式等待】,用一句代碼來解決【驅動器對象.implicitly_wait( 等待時間 )】。他的意思就是在嘗試訪問一個元素時等待一段時間,直到該元素出現,再等一段時間再找下一個元素......
這段等待時間就是我們往【驅動器對象.implicitly_wait( 等待時間 )】傳入的參數,單位是秒,通常都是用10s
from selenium import webdriverChromeDriver = webdriver.Chrome()
ChromeDriver.implicitly_wait(10) # 隱式等待、全局等待ChromeDriver.get('網址')
反正你加上就對了,也不會少塊肉
2、另一種優化方式
1)DesiredCapabilities對象
【DesiredCapabilities】
是 Selenium WebDriver 的一個類,用于設置【驅動器(webdriver)的行為】如瀏覽器類型、版本、平臺等。通過這個類,我們能夠配置【驅動器(webdriver)】在指定的環境執行我們的腳本,可以在不同的環境中運行Selenium測試腳本,支持并行運行多個測試用例在不同的瀏覽器、操作系統和機器上?。
【
DesiredCapabilities
?對象】包含了一系列的鍵值對,每個鍵值對都表示一個特定的【驅動器的行為】 設置:
- 瀏覽器名稱:broswerName
- 版本:version
- 操作系統平臺:platform
- 驅動器是否等待頁面加載完成:pageLoadStrategy
- ......
例子:
from selenium.webdriver import DesiredCapabilities #頭文件# 創建DesiredCapabilities對象的寫法 capabilities = DesiredCapabilities.EDGE #適用于Edge瀏覽器的驅動器 # capabilities = DesiredCapabilities.FIREFOX #適用于火狐瀏覽器的驅動器 # capabilities = DesiredCapabilities.Chrome #適用于谷歌瀏覽器的驅動器# 設置它的一些行為屬性 capabilities['browserName'] = 'EDGE' #指定是EDGE瀏覽器的環境 capabilities['browserVersion'] = 'latest' #指定是最新版本 capabilities['platformName'] = 'WINDOWS' #指定是window操作系統平臺# 都設置好之后,在創建驅動器對象的時候,把DesiredCapabilities參數加進去 driver = webdriver.EDGE(desired_capabilities=capabilities)
2)Options對象
webdriver.Edge() 方法本身并不接受任何參數,它只是創建一個 Edge 瀏覽器的驅動器,并使用默認的設置。
Options對象用于操作【瀏覽器驅動器的各種屬性】,Option類通常與DesiredCapabilities一起使用。
使用【驅動器Options( )】可以設置各個瀏覽器的不同選項和參數,例如:
- 設置瀏覽器窗口大小
- 設置瀏覽器的啟動位置
- 配置瀏覽器的代理服務器
- 設置瀏覽器的用戶代理字符串
- 啟用或禁用瀏覽器的javascript執行等。
下面是ChromeOptions類可用的和最常用的參數列表:
- start-maximized: 最大化模式打開
- Chrome incognito: 無痕瀏覽打開瀏覽器
- headless: 無頭模式(后臺運行)
- disable-extensions: 禁用Chrome瀏覽器上現有的擴展
- disable-popup-blocking: 禁用彈窗
- make-default-browser: 設置Chrome為默認瀏覽器
- version: 打印chrome瀏覽器版本
- disable-infobars: 防止Chrome顯示“Chrome正在被自動化軟件控制”的通知
例子:
注意,.add_argument('--參數') 等于.add_argument('參數'),通常來說推薦用.add_argument('--參數') ,因為前面的“--”表示這是一個選項,可選可不選,有沖突時以適配的優先,更靈活
from selenium.webdriver.firefox.options import Options# 創建FirefoxOptions對象 options = Options() options.add_argument('--headless') # 設置無頭模式 options.add_argument('--disable-extensions') # 禁用瀏覽器擴展 options.add_argument("--window-size=1920,1080") # 設置瀏覽器窗口大小 options.add_argument("--disable-images") # 禁用圖片加載
3)搭配優化腳本執行速率
?前面講得比較細,其實我們用不到那么多參數,所以我就沒有給太多使用案例
我們只講平時爬蟲我么們常用的幾個寫法
1、DesiredCapabilities對象設置【不等待頁面加載完成,立即返回】
在默認情況下,WebDriver 會等待頁面完全加載完成,然后再繼續執行腳本。這可能會導致腳本執行速度較慢,特別是在加載大型頁面或網絡條件較差的情況下。
;
這可以提高腳本的執行速度,但可能會導致腳本在頁面加載完成之前嘗試訪問頁面元素。但是一般加了沒錯,加了就對了
from selenium.webdriver import DesiredCapabilities# 創建一個【EDGE的驅動器】的【capabilities對象】 desired_capabilities?=?DesiredCapabilities.EDGE # 直接返回,不再等待界面加載完成 desired_capabilities["pageLoadStrategy"] = "none"
2、搭配option不加載圖片,加快頁面加載速度
options = webdriver.EdgeOptions() options.add_argument("--disable-images") # 禁用圖片加載 # 下面這種寫法也是禁用圖片加載,一樣效果 # options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
3、完整例子
(結合兩個優化,反正你以后創建webdriver你就這么復制就行)
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities# 這行代碼創建了一個 DesiredCapabilities 對象,用于設置 Edge 驅動器的行為
desired_capabilities = DesiredCapabilities.EDGE
# 直接返回,不再等待界面加載完成
desired_capabilities["pageLoadStrategy"] = "none"# 設置webdriver的option選項對象
options = webdriver.EdgeOptions()
options.add_argument("--disable-images") # 禁用圖片加載
# options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})driver = webdriver.Edge(options=options)
driver.implicitly_wait(10) # 隱式等待、全局等待driver.get('https://kns.cnki.net/kns8s/AdvSearch?crossids=YSTT4HG0%2CLSTPFY1C%2CJUP3MUPD%2CMPMFIG1A%2CWQ0UVIAA%2CBLZOG7CK%2CPWFIRAGL%2CEMRPGLPA%2CNLBO1Z6R%2CNN3FJMUV')
?六、CSS選擇器
前面我們選擇的元素都是很基礎很基礎的,直接用當前元素的【標簽名、id名、class名】來選
但是如果有多個元素都叫同名怎么辦,例如:<div class="content"></div>、<ul class="content"></ul>、<span?class="content"></span>......
那么有過開發經驗的應該知道,css的層級結構還是比較可靠的,這里我具體就不展開敘述了,有興趣自己查 “css選擇器語法”,基本和爬蟲這里大差不差,常用的我說一下吧:
- “>” 跟著上一元素的直系子元素:
- 元素?> 直系后代元素1?> 直系后代元素2?> ......?
- “空格” 跟著上一元素的任意子元素,隔代后代元素也行:
- 元素?后代元素1 后代元素2......
- 要同時選擇1個以上的元素,那就用逗號
- 元素1,元素2,......
- 但是注意,要選一個父元素里的兩個子元素,逗號后面不能漏了層級關系
- 例子:#main下的ul和p標簽元素:#main ul, p? ×錯? ? ??#main ul, #main p √對
- 要選一個元素和緊挨著的下一個元素,比如<h3>...</h3><span>...</span>
- 元素1 + 元素2,例子:h3 + span
- 要選一個元素后面的所有元素,比如<h3>...</h3><span>...</span><span>...</span>
- 元素1 ~ 元素2,例子:h3 ~?span
- 父元素的第n個子節點,比如<span><div>...</div><div>...</div></span>
- 元素:nth-child(n),例子:span:nth-child(2)
- 也可根據屬性值來選,比如:<div data-md-component="container"></div>
- 元素[屬性="屬性值"],例子:div[data-md-component="container"]
【重點】
這都不是重點,重點是以前我一直傻傻自己在代碼測試自己有沒有找到這個元素
;
殊不知在檢查頁面可以直接搜索查找我們的定位元素有沒有定位到
;
在HTML部分【Ctrl + F】查找,把你猜想到的css選擇器寫法寫上去,看看有沒有定位到,沒有就一直試,直到定位上去,這樣就不用再到代碼里一遍一遍試錯了
【語法】
就是把【.find_element( )】或【.find_elements( )】的第一個參數寫成【By.CSS_SELECTOR】
titleList = ChromeBrowser.find_elements(By.CSS_SELECTOR, ".result div div .c-title a") for title in titleList:print(title.text)
七、鼠標、鍵盤事件
現在我們前面的基礎其實跟request、scrapy差不多,重點來了,selenium如何做到自動化檢測、爬蟲網站的?
那就是模仿鼠標的點擊事件、鍵盤事件......等等
1、(常用的)輸入、鼠標左鍵點擊
鍵盤輸入事件:【元素.sent_keys("要輸入的內容")】
- 要先用【元素.clean()】清空一下輸入框的內容,以免有別的文字
- 這里留意,如果你的文字輸入內容是“...\n”后帶上“換行符”,就代表摁下【回車】了 (但是如果有的輸入框沒有寫摁下回車事件,那就沒用,就還得點擊【發送按鈕】才行)
# 獲取輸入框元素 inputElement = ChromeBrowser.find_element(By.ID, 'kw')# 先清空輸入框里的文字 inputElement.clear() # 然后填入文字,并同時回車 inputElement.send_keys('岑梓銘\n')
鼠標點擊事件:【元素.click()】
inputElement = ChromeBrowser.find_element(By.ID, 'kw') inputElement.clear() inputElement.send_keys('岑梓銘')# 獲取【發送按鈕】元素 enterButton = ChromeBrowser.find_element(By.ID, 'su') # 輸入框沒有自動摁回車,這里用點擊事件來點擊發送按鈕 enterButton.click()
【小例子】
from selenium import webdriver
from selenium.webdriver.common.by import ByChromeBrowser = webdriver.Chrome()
ChromeBrowser.implicitly_wait(10) # 隱式等待、全局等待ChromeBrowser.get('https://www.baidu.com')inputElement = ChromeBrowser.find_element(By.ID, 'kw')
enterButton = ChromeBrowser.find_element(By.ID, 'su')inputElement.clear()
inputElement.send_keys('岑梓銘')
enterButton.click()titleList = ChromeBrowser.find_elements(By.CSS_SELECTOR, ".result div div .c-title a")
for title in titleList:print(title.text)
2、(偶爾用)其他的事件
之前我們對web元素做的操作主要是:選擇元素,然后?點擊元素?或者?輸入?字符串。
還有沒有其他的操作了呢?有。
比如:鼠標右鍵點擊、雙擊、移動鼠標到某個元素、鼠標拖拽等。這些操作,可以通過 Selenium 提供的?ActionChains
?類來實現。常用有:
- 單擊元素?:actions.click( 元素 ).perform( )
- 在當前聚焦元素輸入框輸入內容:actions.send_keys("內容").perform( )
- 鼠標懸停不點擊:actions.move_to_element( 元素 ).perform( )
- ?雙擊元素?:actions.double_click(?元素 ).perform( )
- ?右鍵點擊元素:actions.context_click(?元素 ).perform( )
- 拖拽元素:actions.drag_and_drop( 拖拽元素, 目標元素 ).perform( )
- 鼠標摁住不放:actions.click_and_hold( 元素 ).perform( )
- 摁下Enter鍵并釋放:actions.key_down( Keys.ENTER ).key_up( Keys.ENTER?).perform( )
例子:
百度的“更多”就是要鼠標懸停上去不點擊,才會出現這些元素
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome() driver.implicitly_wait(5)driver.get('https://www.baidu.com/')# 開始使用action_chains來進行鼠標事件 #導入頭文件 from selenium.webdriver.common.action_chains import ActionChains # 創建action_chains對象 ac = ActionChains(driver)# 鼠標移動到 元素上 ac.move_to_element(#這里填入獲取的元素對象,而且用的是屬性選擇driver.find_element(By.CSS_SELECTOR, '[name="tj_briicon"]') ).perform()
3、凍結窗口
像剛剛那個情況我們要鼠標懸停,隱藏的東西才會出現;但是當鼠標一離開,隱藏元素馬上消失,那這樣我們怎么找到這隱藏元素呢?
我們可以使用一個技巧,當我們在瀏覽器控制臺輸入【debugger】,網頁就會凍住,進行調試模式
那么我們再寫一個這樣的一行代碼:
setTimeout(function(){debugger}, 5000)
學過前端的應該明白,意思就是說用setTimeout這個定時器函數,在設定的時間內再觸發debbug事件
八、切換頁面窗口
當我們在一個頁面點擊某個鏈接跳轉到一個新頁面的時候,我們的腳本程序并不會自動切換到新頁面,這時候我們如果還想在新的窗口進行一些操作,就會報錯
錯誤例子:
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome() driver.implicitly_wait(10) # 隱式等待、全局等待driver.get('https://www.byhy.net/cdn2/files/selenium/sample3.html')# 這是一個超鏈接元素,我們在原頁面點擊這個元素進行跳轉新頁面 link = driver.find_element(By.TAG_NAME, 'a') link.click()# 這里我們以為自己跳轉到了一個搜索網頁,我們希望獲取搜索框并輸入內容 # input = driver.find_element(By.ID, 'sb_form_q') # input.send_keys('岑梓銘') # 但是很明顯是錯的,因為我們并沒有切換到新的頁面,我們還在原來的頁面,所以不可能找到這個新頁面的元素
那么selenium提供一個工具:【驅動器.current_window_handle】
【驅動器.current_window_handle】能返回包含這個驅動器打開的瀏覽器的所有窗口信息的對象數組,每個窗口對象的信息包括【窗口標題】、【窗口url】
那么我們就可以再搭配【驅動器.switch_to.window( 窗口對象 )】來切換窗口了,只需要設置一個循環,用【驅動器.switch_to.window( 窗口對象 )】一直切換,直到當前窗口的【驅動器.title】或【驅動器.current_url】是我們要的頁面,就退出切換窗口循環
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome() driver.implicitly_wait(10) # 隱式等待、全局等待driver.get('https://www.byhy.net/cdn2/files/selenium/sample3.html')# 這是一個超鏈接元素,我們在原頁面點擊這個元素進行跳轉新頁面 link = driver.find_element(By.TAG_NAME, 'a') link.click() #----------------------------【原窗口】--------------------------------#---------------------------【跳轉窗口】-------------------------------- # 獲取所有窗口句柄 all_windows = driver.window_handles# 切換到新窗口 for window in all_windows:driver.switch_to.window(window)# 通過窗口標題字符串判斷if "必應" in driver.title:break# 通過窗口url判斷if "https://cn.bing.com/" in driver.current_url:break# 現在就可以獲取新窗口元素并操作了 input = driver.find_element(By.ID, 'sb_form_q') input.send_keys('岑梓銘\n')
如果我們還要回到原來的窗口頁面,那么就在切換新窗口之前,用【驅動器.current_window_handle】保存當前原頁面的窗口對象
然后最后再用【驅動器.switch_to.window( 窗口對象 )】切換回去就行
完整代碼
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome() driver.implicitly_wait(10) # 隱式等待、全局等待driver.get('https://www.byhy.net/cdn2/files/selenium/sample3.html')# 這是一個超鏈接元素,我們在原頁面點擊這個元素進行跳轉新頁面 link = driver.find_element(By.TAG_NAME, 'a') link.click() #----------------------------【原窗口】--------------------------------#---------------------------【跳轉窗口】-------------------------------- # 獲取當前窗口句柄 current_window = driver.current_window_handle# 獲取所有窗口句柄 all_windows = driver.window_handles# 切換到新窗口 for window in all_windows:driver.switch_to.window(window)# 通過窗口標題字符串判斷if "必應" in driver.title:break# 通過窗口url判斷if "https://cn.bing.com/" in driver.current_url:break# 現在就可以獲取新窗口元素并操作了 input = driver.find_element(By.ID, 'sb_form_q') input.send_keys('岑梓銘\n')#---------------------------【回到原窗口】-------------------------------- driver.switch_to.window(current_window)
九、selenuim操作JS
有的時候我們還需要通過操作JS來實現一些復雜業務
基本語法就是(不傳參數):【驅動器對象.execute_script( "JS的操作,要字符串形式" )】
還有一種寫法是(要傳參):【驅動器對象.execute_script( "JS的操作" ),參數1,參數2,......】
比如我們只需要簡單用JS在控制臺輸出1個字符串,不用參數就【驅動器對象.execute_script( "JS的操作,要字符串形式" )】
js = "console.log('hello')" driver.execute_script(js)
那么有時我們需要指定操作某一個元素,就需要把這個對象當成參數傳給JS
用參數,就【驅動器對象.execute_script( "JS的操作" ),參數1,參數2,......】
例子1:
豆瓣網:https://www.douban.com
假設我們想點一個 “不在視覺范圍的一個元素”,如果單純只是想獲取這個元素是可以的;但是如果那你想自動化去點擊,就不行了,因為這個元素要往下劃才能顯示在屏幕,才能看到才能點擊
直接點擊這個元素報錯
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome( ) driver.get('https://www.douban.com/')# 點擊一個在很下面的屏幕往下滑才看得到的元素 link = driver.find_element(By.CSS_SELECTOR,'#anony-movie .sidenav .section-title a') link.click()
那么現在就要利用JS,讓屏幕下劃,直到這個元素出現在屏幕視野
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome( ) driver.get('https://www.douban.com/')# 利用selenuim操控JS讓滾動條的拖動1500 js = 'scrollTo(0,1500)' driver.execute_script(js)# 現在元素在視線范圍,可以獲取并點擊了 link = driver.find_element(By.CSS_SELECTOR,'#anony-movie .sidenav .section-title a') link.click()?
那如果我們實在不好確定到底該往下劃多少,可以這樣寫
? from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome( ) driver.get('https://www.douban.com/')# 如果不確定到底要滑動多少才找得到元素,可以這樣寫 link = driver.find_element(By.CSS_SELECTOR,'#anony-movie .sidenav .section-title a') driver.execute_script("arguments[0].scrollIntoView({block:'center',inline:'center'})", link ) # 其中 arguments[0] 就指代了后面的第一個參數link對應的js對象, # js對象的 scrollIntoView 方法,就是讓元素滾動到可見部分 # block:'center' 指定垂直方向居中 # inline:'center' 指定水平方向居中# 現在元素在視線范圍,可以獲取并點擊了 link.click()?
例子2:
知網上當我們點擊【高級搜索】之后的搜索頁面,我們會發現那些下拉選項元素要鼠標點擊才會出現,點擊的時候我們會發現,原理是這個元素的css的樣式【display: none】就是消失;【display: block】就是出現
;
那么我們只需要用【驅動器對象.execute_script( "" )】
from selenium import webdriver from selenium.webdriver.common.by import Bydriver = webdriver.Chrome( )driver.get('https://kns.cnki.net/kns8s/AdvSearch?crossids=YSTT4HG0%2CLSTPFY1C%2CJUP3MUPD%2CMPMFIG1A%2CWQ0UVIAA%2CBLZOG7CK%2CPWFIRAGL%2CEMRPGLPA%2CNLBO1Z6R%2CNN3FJMUV')# 獲取到下拉菜單的元素 optionSelect = driver.find_element(By.CSS_SELECTOR, ".sort .sort-list")# 使用 JavaScript 將元素的 display 樣式設置為 block driver.execute_script("arguments[0].style.display = 'block';", optionSelect)#可打個斷點看效果 driver.quit()
還有很多知識點,我將分幾篇來講述,先到這吧