python - 可靠地检测页面加载或超时,Selenium 2

标签 python webdriver selenium-webdriver

我正在使用 Selenium 2(2.33 版 Python 绑定(bind),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 调用永远挂起。发生这种情况时,通常浏览器实际上还没有完成页面加载(“throbber”仍在旋转),但几十分钟过去了,超时不会触发。但有时页面似乎已完全加载,但脚本仍未继续。

什么给了?如何使超时可靠地工作?有没有更好的方法来请求等待页面加载(如果不能对内容做出任何假设)?

注意:WebDriverException 的强制性捕获和忽略已被证明是必要的,以确保它从页面中提取尽可能多的链接,无论页面中的 JavaScript 是否正在做一些有趣的事情DOM(例如,我曾经在提取 HREF 属性的循环中遇到“陈旧元素”错误)。

注意:这个问题在本网站和其他地方有很多变体,但它们都有细微但关键的差异,这使得答案(如果有的话)无用我,或者我已经尝试了这些建议,但它们不起作用。 准确回答我提出的问题。

最佳答案

我遇到了类似的情况,因为我使用 Selenium 为一个相当知名的网站服务编写了屏幕截图系统,并且遇到了同样的困境:我对正在加载的页面一无所知。

在与一些 Selenium 开发人员交谈后,答案是各种 WebDriver 实现(例如 Firefox Driver 与 IEDriver)对页面何时被认为已加载或不被 WebDriver 返回控制做出不同的选择。

如果你深入研究 Selenium 代码,你可以找到尝试做出最佳选择的地方,但是由于有很多事情可能导致正在寻找的状态失败,比如多个帧,而一个不不及时完成,有司机明明就是不回来的情况。

有人告诉我,“这是一个开源项目”,它可能不会/不能针对所有可能的情况进行更正,但我可以在适用的情况下进行修复并提交补丁。

从长远来看,这对我来说有点多,所以和你一样,我创建了自己的超时过程。因为我使用 Java,所以我创建了一个新线程,它在达到超时时尝试做几件事来让 WebDriver 返回,即使有时只是按下某些键让浏览器响应也能奏效。如果它没有返回,那么我会终止浏览器并重试。

再次启动驱动程序已经为我们处理了大多数情况,就好像浏览器的第二次加载允许它处于更稳定的状态(请注意,我们是从 VM 启动的,浏览器不断地想要检查更新并运行最近未启动时的某些例程)。

另一部分是我们首先启动一个已知的 url 并确认有关浏览器的某些方面,并且我们实际上能够在继续之前与其进行交互。通过这些步骤,失败率非常低,在所有浏览器/版本/操作系统(FF、IE、CHROME、Safari、Opera、iOS、Android 等)上进行 1000 次测试后,失败率约为 3%

最后但同样重要的是,对于您的情况,听起来您只需要捕获页面上的链接,而不需要完全的浏览器自动化。我可能会采用其他方法,即 cURL 和 linux 工具。

关于python - 可靠地检测页面加载或超时,Selenium 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18729483/

相关文章:

java - 常规/katalon : Validate sequence of list

python - 插值和估计不确定性

python - 如何编辑已有的规则?

java - 如何使用 Java 在 Selenium Webdriver 中捕获屏幕截图而不调整窗口大小

ruby - Selenium2 WebDriver Ruby => 如何点击隐藏链接

java - 如何使用带有 Java 的 Selenium WebDriver 将鼠标悬停在 Web 元素上

python - 在后台运行 webdriver selenium

python - 如何使用 python 绘制简单正弦波的死区

python - 计算python中递归算法中的操作数

javascript - 如何使用 Selenium 按住非修改键(空格键)?