selenium自動爬蟲工具

一、介紹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個參數:

  1. 第一個是【通過標簽名、id選擇器、class選擇器】哪一個方式來選擇元素
    • 需要用By這個對象,需要另外導入By的頭文件
    • 通過標簽名就是:By.TAG_NAME
    • 通過id名就是:By.ID
    • 通過類名就是:By.CLASS_NAME
  2. 第二個是就是具體的【標簽名、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()

還有很多知識點,我將分幾篇來講述,先到這吧

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62775.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62775.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62775.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity開發數字孿生項目

前言&#xff1a;記錄下自己用Unity開發數字孿生項目&#xff0c;所用到的知識點、功能點以及對項目認知總結&#xff0c;當然還有開發過程中所遇到的坑。此篇博客也是會隨時進行更新。 &#x1f60a;屏幕前看到此片文章的開發者們在此類項目開發過程中少走些彎路&#xff0c;希…

node利用路由搭建web實例

npm init npm i express body-parser cookie-parser 封裝web實例 搭建路由 導出web 應用實例注冊

量化交易系統開發-實時行情自動化交易-8.25.真格(澎博財經旗下)平臺

19年創業做過一年的量化交易但沒有成功&#xff0c;作為交易系統的開發人員積累了一些經驗&#xff0c;最近想重新研究交易系統&#xff0c;一邊整理一邊寫出來一些思考供大家參考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下來會對于真格&#xff08;澎博財經…

QT JSON文件解析

參考博客 https://blog.csdn.net/cpp_learner/article/details/118421096 1 打開文件&#xff0c;讀取全部內容 QFile file("../Json/js.json"); if (!file.open(QFile::ReadOnly | QFile::Text)) {qDebug() << "cant open error!";return; }// 讀…

面試常見-Java 原生實現常見數據結構

Java 原生實現常見數據結構 文章目錄 Java 原生實現常見數據結構一、引言二、數組&#xff08;Array&#xff09;&#xff08;一&#xff09;概念&#xff08;二&#xff09;代碼實現 三、鏈表&#xff08;Linked List&#xff09;&#xff08;一&#xff09;概念&#xff08;二…

1. 機器學習基本知識(5)——練習題(參考答案)

20.&#x1f517;本章代碼筆記&#x1f4d3;鏈接&#xff08;需要&#x1fa9c;&#xff09;&#xff1a;&#xff08;01_the_machine_learning_landscape.ipynb - Colab (google.com)&#xff09; 如果你不想通過上面的官方網址下載本章的筆記&#xff0c;還可以在本篇博文的…

通常一個 Xml 映射文件,都會寫一個 Dao 接口與之對應, 請問,這個 Dao 接口的工作原理是什么?Dao 接口里的方法, 參數不同時,方法能重載嗎?

Dao 接口 即 Mapper 接口 。接口 的 全 限 名 &#xff0c;就是 映 射 文 件 中 的 namespace 的值 &#xff1b; 接口 的 方 法 名 &#xff0c; 就 是 映 射 文 件 中 Mapper 的 Statement 的 id 值&#xff1b; 接 口 方 法 內 的 參數 &#xff0c; 就 是 傳 遞 給 sql 的參…

硬件設計 | Altium Designer軟件PCB規則設置

基于Altium Designer&#xff08;24.9.1&#xff09;版本 嘉立創PCB工藝加工能力范圍說明-嘉立創PCB打樣專業工廠-線路板打樣 規則參考-嘉立創 注意事項 1.每次設置完規則參數都要點擊應用保存 2.每次創建PCB&#xff0c;都要設置好參數 3.可以設置默認規則&#xff0c;將…

WebDAV服務不能上傳大文件,文件超過50M報錯[0x800700DF]怎么辦?

這個問題需要分別從服務端和客戶端解決。 1.Windows客戶端 解除50M文件限制&#xff0c;Windows訪問Webdav服務時&#xff0c;大于50M文件提示錯誤[錯誤:0x800700DF] 部署了webdav&#xff0c;Windows10映射網絡磁盤&#xff0c;傳輸文件超過大約50MB的文件會彈出“0x800700…

安全基礎學習-keil調試匯編代碼

初始目的是為了通過匯編編寫CRC功能。 但是基礎為0&#xff0c;所以目前從搭建工程開始記錄。 大佬繞路。 &#xff08;一&#xff09;創建項目 1. 新建項目 打開 Keil uVision。選擇 Project -> New uVision Project 創建一個新項目。選擇你的目標設備&#xff08;如 AR…

安裝qt 5.15.2筆記

撰文是2024年12月 最終實現了 1、用梯子下載了離線包5.14.2&#xff0c;最后沒用 2、用內地鏡像在線安裝5.15.2&#xff0c;3分鐘裝完 正文開始&#xff0c;qt官方簡稱官方。 官方包官方自5.15.X起&#xff0c;不再提供的exe/run安裝包https://download.qt.io/archive/qt/ …

Redis Java 集成到 Spring Boot

Hi~&#xff01;這里是奮斗的明志&#xff0c;很榮幸您能閱讀我的文章&#xff0c;誠請評論指點&#xff0c;歡迎歡迎 ~~ &#x1f331;&#x1f331;個人主頁&#xff1a;奮斗的明志 &#x1f331;&#x1f331;所屬專欄&#xff1a;Redis &#x1f4da;本系列文章為個人學習筆…

【Syncfusion系列】Diagram 雜談 第三篇 序列化和反序列化

目錄 序列化保存C# 代碼示例&#xff0c; 方式1 &#xff1a;C# 代碼示例&#xff0c; 方式2 &#xff1a; 反序列化加載C# 代碼示例, 方式1&#xff1a;C# 代碼示例, 方式2&#xff1a; **如何序列化自定義屬性**序列化和反序列化都存在的一個問題解決方式 圖表是否已修改&…

麒麟信安推出支持信創PC的新一代云桌面方案,助力政務信創高效安全運維

12月11日&#xff0c;在第二屆國家新一代自主安全計算系統產業集群融通生態大會上&#xff0c;麒麟信安發布了支持信創PC的新一代云桌面方案&#xff0c;該方案是基于國際TCI架構實現國產PC機云化納管在國內的首次發布&#xff0c;并與銀河麒麟桌面操作系統、長城國產PC整機實現…

中國科學院2001年數據結構試題

一、單項選擇題(每空2分&#xff0c;共20分) 1&#xff0e;下列函數中漸近時間復雜度最小的是( )。 A&#xff0e;T1(n)nlog2n5000n B&#xff0e;T2(n)n2-8000n C&#xff0e;T3(n)nlog221-6000n D&#xff0e;T4(n)2nlog2n-7000n 2&#xff0e;線性表的靜態鏈表存儲結構與順序…

MySQL數據表記錄刪操作

刪除操作&#xff1a;作用刪除表里的記錄行&#xff08;都是整行整行的刪除的&#xff09; 1.單表的刪除 語法 delete from 表名 where 要刪除的記錄篩選條件; 案例&#xff1a;刪除員工編號大于203的員工信息 delete from employees where employee_id>203; 2.多表的刪除…

網絡原理04

可靠傳輸&#xff0c;是TCP最核心的特性 可靠傳輸不是說數據100%傳輸給接收方了 1&#xff09;發送方發出數據后&#xff0c;能過知道接收方是否收到數據 2&#xff09;一旦發現對方沒收到&#xff0c;可以通過一定的方法”補救” 1. 確認應答 發送方&#xff0c;把數據已…

微信小程序5-圖片實現點擊動作和動態加載同類數據

搜索 微信小程序 “動物覓蹤” 觀看效果 感謝閱讀&#xff0c;初學小白&#xff0c;有錯指正。 一、功能描述 a. 原本想通過按鈕加載背景圖片&#xff0c;來實現一個可以點擊的搜索button&#xff0c;但是遇到兩個難點&#xff0c;一是按鈕大小調整不方便&#xff08;網上搜索…

Java里局部變量和成員變量的隱式初始化

注&#xff1a;本文是對另一篇文檔&#xff08; https://blog.csdn.net/duke_ding2/article/details/142365872 &#xff09;的補充。 文章目錄 環境初始化局部變量&#xff08;棧&#xff09;成員變量&#xff08;堆&#xff09;其它數組 分析安全性性能成員變量 VS. 局部變量…

孚盟云 MailAjax.ashx SQL注入漏洞復現

0x01 產品簡介 上海孚盟軟件有限公司是一家外貿SaaS服務提供商,也是專業的外貿行業解決方案專業提供商。 全新的孚盟云產品,讓用戶可以用云模式實現信息化管理,讓用戶的異地辦公更加流暢,大大降低中小企業在信息化上成本,用最小的投入享受大型企業級別的信息化服務,主要…