5 回答

TA貢獻1862條經驗 獲得超7個贊
我遇到了同樣的問題,它最初可以工作,但在我們使用 Selenium 的網站進行更新后,它停止在無頭模式下工作,但繼續在非無頭模式下工作。經過 2 天的研究網絡最深和最黑暗的深度以及大量的試驗和錯誤,終于找到了問題所在。
我嘗試了網上列出的所有方法以及更多方法,但在我找到這個方法之前都沒有任何效果。
在無頭 chrome 模式下,用戶代理如下所示: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,如 Gecko)?HeadlessChrome?/60.0.3112.50 Safari/537.36
服務提供商更新了他們的代碼以識別 HeadlessChrome 部分,這會導致選項卡崩潰,進而破壞 Selenium 用戶會話。
這導致上述問題在其中一個異常中觸發。
為了解決這個問題,我使用了一個名為 fake_headers 的插件(https://github.com/diwu1989/Fake-Headers):
from fake_headers import Headers
header = Headers(
? ? browser="chrome",? # Generate only Chrome UA
? ? os="win",? # Generate only Windows platform
? ? headers=False # generate misc headers
)
customUserAgent = header.generate()['User-Agent']
options.add_argument(f"user-agent={customUserAgent}")
雖然這只是解決方案的一半,因為我只想要 Windows 和 Chrome 標頭,并且 fake_headers 模塊不包含最新的 Chrome 瀏覽器,并且列表中包含許多舊版本的 Chrome,如在此文件中所示 https:?// github.com/diwu1989/Fake-Headers/blob/master/fake_headers/browsers.py。我運行 Selenium 的特定網站的某些功能僅適用于較新版本的 Chrome,因此當舊版本的 Chrome 通過用戶代理標頭傳遞時,該網站上的某些功能實際上會停止工作。因此,我需要更新 fake_headers 模塊中的 browsers.py 文件,以僅包含我想要包含的 Chrome 版本。因此,我刪除了 Chrome 的所有舊版本,并創建了一個精選版本列表(每個版本都經過單獨測試以在相關網站上運行,并刪除了不能運行的版本)。最終得到了以下列表,我可以對其進行擴展,但暫時還沒有。
chrome_ver?=?[ ????'90.0.4430',?'84.0.4147',?'85.0.4183',?'85.0.4183',?'87.0.4280',?'86.0.4240',?'88.0.4324',?'89.0.4389',?'92.0.4515',?'91.0.4472',?'93.0.4577',?'93.0.4577']
希望這可以幫助人們減輕兩天的壓力和混亂。

TA貢獻1805條經驗 獲得超9個贊
如果腳本在沒有無頭模式的情況下工作得很好,則窗口大小可能存在問題。除了指定 --no-sandbox 選項外,嘗試更改傳遞給網絡驅動程序的窗口大小
chrome_options.add_argument('--window-size=1920,1080')
這個窗口大小適合我的情況。
即使這不起作用,您可能需要添加之前回答的等待計時器,因為與 UI 模式下的瀏覽器相比,無頭模式下的渲染工作方式不同。
無頭模式渲染參考 - https://www.toolsqa.com/selenium-webdriver/selenium-headless-browser-testing/

TA貢獻1842條經驗 獲得超13個贊
我也遇到過類似的情況。我在網上嘗試了很多解決方案,例如指定分辨率,但沒有任何效果,直到這:
self.chrome_options.add_argument('user-agent="MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"')
所以看來你需要將UA添加到chrome選項中,這樣selenium驅動程序就不會在無頭模式下崩潰。

TA貢獻1858條經驗 獲得超8個贊
我會以某種方式重構代碼,直到元素出現在網頁上:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(wd, 10).until(EC.presence_of_element_located((By.ID, 'username'))).send_keys(args.usr)
WebDriverWait(wd, 10).until(EC.presence_of_element_located((By.ID,'password'))).send_keys(args.pwd)
WebDriverWait(wd, 10).until(EC.presence_of_element_located((By.ID, 'login-btn'))).click()
通常,與某些條件結合使用WebDriverWait應優先于隱式等待或time.sleep()。這里詳細解釋一下原因。
其他需要仔細檢查的事情是元素是否具有用于搜索的 ID,以及這些元素是否位于 iframe 內。
添加回答
舉報