我正在尝试获取此网站论坛的整个 html 网页。只有向下滚动后才能加载评论部分。滚动一段时间后,您会发现最终(在第 4 页)出现一个 Load Next Page 按钮,您必须单击该按钮才能获取后续评论。经过大量搜索后,下面的代码可以很好地获取评论的最后一页。其中大部分内容也取自 stackoverflow post 和 this。
仅供参考,我使用的是 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()
或其他任何东西作为潜在的解决方法,但问题仍然存在。
模式下工作,并在无头模式下给出相同的错误。 这是因为在
无头模式 下,如果您没有指定 chrome 窗口的大小(通过 driver.set_window_rect(width=1200, height=900)
),那么可能会出现一个弹出窗口,该窗口会覆盖可点击按钮,从而阻止其被点击。
指定窗口大小对我有用,我认为它也应该对你有用。
driver.find_element_by_css_selector('.myButton').click()
到
driver.execute_script("document.querySelector('.myButton').click()")
应该可以。事实上,从 javascript 做所有事情并不是一个坏主意,除非你是“QA 测试”
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)
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")