selenium被識別如何反屏蔽 Selenium無法點擊元素,報錯:ElementClickInterceptedException:element click intercepted

反屏蔽

現在很多網站都加上了對 Selenium 的檢測,來防止一些爬蟲的惡意爬取。即如果檢測到有人在使用 Selenium 打開瀏覽器,那就直接屏蔽。

 

其大多數情況下,檢測基本原理是檢測當前瀏覽器窗口下的 window.navigator 對象是否包含 webdriver 這個屬性。因爲在正常使用瀏覽器的情況下,這個屬性是 undefined,然而一旦我們使用了 Selenium,Selenium 會給 window.navigator 設置 webdriver 屬性。很多網站就通過 JavaScript 判斷如果 webdriver 屬性存在,那就直接屏蔽。

 

這邊有一個典型的案例網站:

這個網站就是使用了上述原理實現了 WebDriver 的檢測,如果使用 Selenium 直接爬取的話,那就會返回如下頁面:

 

 

這時候我們可能想到直接使用 JavaScript 直接把這個 webdriver 屬性置空,比如通過調用 execute_script 方法來執行如下代碼:

Object.defineProperty(navigator, "webdriver", {get: () => undefined})

 

這行 JavaScript 的確是可以把 webdriver 屬性置空,但是 execute_script 調用這行 JavaScript 語句實際上是在頁面加載完畢之後才執行的,執行太晚了,網站早在最初頁面渲染之前就已經對 webdriver 屬性進行了檢測,所以用上述方法並不能達到效果。

 

在 Selenium 中,我們可以使用 CDP(即 Chrome Devtools-Protocol,Chrome 開發工具協議)來解決這個問題,通過 CDP 我們可以實現在每個頁面剛加載的時候執行 JavaScript 代碼,執行的 CDP 方法叫作 Page.addScriptToEvaluateOnNewDocument,然後傳入上文的 JavaScript 代碼即可,這樣我們就可以在每次頁面加載之前將 webdriver 屬性置空了。另外我們還可以加入幾個選項來隱藏 WebDriver 提示條和自動化擴展信息,代碼實現如下:

from selenium import webdriver
from selenium.webdriver import ChromeOptions

option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
   'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
browser.get('https://antispider1.scrape.cuiqingcai.com/')

 

這樣整個頁面就能被加載出來了:

 

 

對於大多數的情況,以上的方法均可以實現 Selenium 反屏蔽。但對於一些特殊的網站,如果其有更多的 WebDriver 特徵檢測,可能需要具體排查。

 

---原文來源於崔慶才

 

Selenium無法點擊元素,報錯:ElementClickInterceptedException:element click intercepted

 

我們在進行selenium UI自動化測試時,可能會遇到元素可以定位到,但不可點擊的情況,如下錯誤:

這個問題有兩種解決方式:

方式一:

element = driver.find_element_by_xpath("表達式")
driver.execute_script("arguments[0].click();", element)

方式二:

element = driver.find_element_by_xpath('表達式')
webdriver.ActionChains(driver).move_to_element(element ).click(element ).perform()

這兩種方式都可以解決此問題(我採用的第一種,畢竟簡潔嘛)

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章