我正在使用 Selenium 2(2.33 版 Python 绑定,Firefox 驱动程序)编写一个通用的网络爬虫。它应该采用任意URL,加载页面并报告所有出站链接。因为 URL 是任意的,所以我无法对页面的内容做出任何假设,因此通常的建议(等待特定元素出现)是不适用的。
我有应该轮询的代码,document.readyState
直到它达到“完成”或 30 秒超时已经过去,然后继续:
def readystate_complete(d):
# AFAICT Selenium offers no better way to wait for the document to be loaded,
# if one is in ignorance of its contents.
return d.execute_script("return document.readyState") == "complete"
def load_page(driver, url):
try:
driver.get(url)
WebDriverWait(driver, 30).until(readystate_complete)
except WebDriverException:
pass
links = []
try:
for elt in driver.find_elements_by_xpath("//a[@href]"):
try: links.append(elt.get_attribute("href"))
except WebDriverException: pass
except WebDriverException: pass
return links
这种工作,但在大约五分之一的页面上,.until
电话永远挂起。发生这种情况时,通常浏览器实际上还没有完成页面加载(“颤动”仍在旋转),但可能会经过数十分钟并且不会触发超时。但有时页面确实似乎已完全加载并且脚本仍然没有继续。
是什么赋予了?如何使超时可靠地工作?有没有更好的方法来请求等待页面加载(如果不能对内容做出任何假设)?
注意: 强迫性的捕捉和忽略WebDriverException
已被证明是必要的,以确保它从页面中提取尽可能多的链接,无论页面内的 JavaScript 是否正在使用 DOM 做有趣的事情(例如,我曾经得到“陈旧的元素" 提取 HREF 属性的循环中的错误)。
注意:在这个网站和其他地方都有很多关于这个问题的变化,但他们都有一个微妙但关键的区别,这使得答案(如果有的话)对我来说毫无用处,或者我已经尝试了这些建议和他们不工作。 请准确回答我提出的问题。