Python Selenium 在无头状态下发生错误?

问题描述 投票:0回答:5

我正在尝试获取此网站论坛的整个 html 网页。只有向下滚动后才能加载评论部分。滚动一段时间后,您会发现最终(在第 4 页)出现一个 Load Next Page 按钮,您必须单击该按钮才能获取后续评论。经过大量搜索后,下面的代码可以很好地获取评论的最后一页。其中大部分内容也取自 stackoverflow postthis

仅供参考,我使用的是 Windows 10,我的 Chrome 驱动程序版本是

76.0.3809.132
。我还使用 PhantomJS 只是为了看看哪个加载速度更快。两个驱动程序
.exe
文件都放置在与我执行脚本的目录相同的目录中。直到今天我还没有遇到任何问题。

import selenium.webdriver as webdriver
from selenium.webdriver.chrome.options import Options

def scrollDownAllTheWay(driver):
    last_height = driver.execute_script("return document.body.scrollHeight")

    while True:
        driver.execute_script("window.scrollTo(0, 100*document.body.scrollHeight);")

        time.sleep(3)

        if "Load next page</button>" in driver.page_source:
            driver.find_element_by_css_selector('.myButton').click()

        new_height = driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:
            break
        last_height = new_height

#Load this and comment out chrome headless code below, if needed.
#driver = webdriver.PhantomJS()

#Chrome driver
options = Options()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)

driver.get("https://www.chessable.com/discussion/thread/58883/official-chessable-launch-schedule-2019/")

scrollDownAllTheWay(driver)

当我使用

webdriver.PhantomJS()
运行上面的脚本(用它替换 Chrome 部分)时,我没有任何问题。该函数一直运行,直到无头浏览器到达最后一页。太棒了。

当我使用

webdriver.Chrome()
无头运行下面的脚本时,遇到以下错误:

ElementClickInterceptedException: Message: element click intercepted: Element <button id="load-next-comments" class="myButton">...</button> is not clickable at point (388, 23). Other element would receive the click: <div class="headerHolder">...</div>   (Session info: headless chrome=76.0.3809.132)

我找不到任何有助于解决这个问题的东西。更奇怪的是,如果禁用 options.add_argument("--headless") 部分(将其注释掉),页面加载得很好,并完成整个页面的滚动。我可以看到最终的点击在本地 Chrome 浏览器中执行,然后看到它在完成后停止滚动和点击。


问题:

为什么无头 Chrome 会话在这里无法正常工作,但非无头版本可以正常工作?

编辑:

我刚刚发现这个post,这可能会有帮助,但我不确定。 注意:我愿意使用其他浏览器驱动程序,例如

FireFox()

或其他任何东西作为潜在的解决方法,但问题仍然存在。

    

python selenium google-chrome selenium-webdriver
5个回答
2
投票

通过将这些选项添加到我的代码中解决了这个问题:

options.add_argument("--window-size=1920,1080") options.add_argument("--start-maximized") options.add_argument("--headless")

PS:我在这里找到了解决方案:
https://github.com/SeleniumHQ/selenium/issues/4685


2
投票
非无头

模式下工作,并在无头模式下给出相同的错误。 这是因为在

无头模式

下,如果您没有指定 chrome 窗口的大小(通过 driver.set_window_rect(width=1200, height=900)),那么可能会出现一个弹出窗口,该窗口会覆盖可点击按钮,从而阻止其被点击。

因此,理想情况下,为窗口指定明确的大小将使所有弹出窗口驻留在其特定位置,并防止隐藏您要单击的按钮。

指定窗口大小对我有用,我认为它也应该对你有用。


1
投票

driver.find_element_by_css_selector('.myButton').click()

driver.execute_script("document.querySelector('.myButton').click()")

应该可以。事实上,从 javascript 做所有事情并不是一个坏主意,除非你是“QA 测试”


1
投票
JavaScript

不是必需的。如果您将

window-size
设置为
headless
模式,它将单击下一页按钮。希望这会有所帮助。

import selenium.webdriver as webdriver from selenium.webdriver.chrome.options import Options def scrollDownAllTheWay(driver): last_height = driver.execute_script("return document.body.scrollHeight") while True: driver.execute_script("window.scrollTo(0, 100*document.body.scrollHeight);") time.sleep(3) if "Load next page</button>" in driver.page_source: driver.find_element_by_css_selector('.myButton').click() print('clicked') new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height options = Options() options.add_argument("--headless") options.add_argument('window-size=1920x1080') driver = webdriver.Chrome(options=options) driver.get("https://www.chessable.com/discussion/thread/58883/official-chessable-launch-schedule-2019/") scrollDownAllTheWay(driver)


要验证代码是否有效,只需在之前或之后截图,您就会知道它正在工作。

import selenium.webdriver as webdriver from selenium.webdriver.chrome.options import Options def scrollDownAllTheWay(driver): last_height = driver.execute_script("return document.body.scrollHeight") i = 1 while True: driver.execute_script("window.scrollTo(0, 100*document.body.scrollHeight);") time.sleep(3) if "Load next page</button>" in driver.page_source: driver.save_screenshot("screenshot_{}.png".format(i)) i = i+1 driver.find_element_by_css_selector('.myButton').click() driver.save_screenshot("screenshot_{}.png".format(i)) i = i + 1 print('clicked') new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height options = Options() options.add_argument("--headless") options.add_argument('window-size=1920x1080') driver = webdriver.Chrome(options=options) driver.get("https://www.chessable.com/discussion/thread/58883/official-chessable-launch-schedule-2019/") scrollDownAllTheWay(driver)



0
投票

options = Options() options.add_argument('--headless') options.add_argument('--window-size=1920,1080') options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36")

	
© www.soinside.com 2019 - 2024. All rights reserved.