我正在开发网络爬虫一段时间,对我来说最常见的问题是等待页面完全加载,包括请求、框架、脚本。我的意思是完全完成。
我使用了几种方法来修复它,但是当我使用多个线程来抓取网站时,我总是会遇到这种问题。 驱动程序会自行打开,通过 URL,不等待并经过下一个 URL。
我的尝试是:
JavascriptExecutor js = (JavascriptExecutor) driver.getWebDriver();
String result = js.executeScript("return document.readyState").toString();
if (!result.equals("complete")) {
Thread.sleep(1000)
}
}
wait.until(ExpectConditions.visibilityOfElementTLocation(By.xpath((;
当我运行单线程代码时,我对页面没有任何问题,但是当我使用多线程时,它变成了一场噩梦。网络无法像单线程那样处理网页,这就是为什么我需要等待一段时间。我正在寻找一个确切的解决方案。有没有进度侦听器或类似的东西?
我在等你的建议。
类似的问题:
硒 -- 如何等到页面完全加载
等待document.readyState
被complete
并不是确保元素的存在、可见性或可交互性的完全证明方法。
因此,函数:
JavascriptExecutor js = (JavascriptExecutor) driver.getWebDriver();
String result = js.executeScript("return document.readyState").toString();
if (!result.equals("complete")) {
Thread.sleep(1000)
}
}
甚至等待jQuery.active == 0
:
public void WaitForAjax2Complete() throws InterruptedException
{
while (true)
{
if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){
break;
}
Thread.sleep(100);
}
}
将是一个纯粹的开销。
您可以在以下位置找到一些相关的讨论:
- Selenium IE WebDriver 仅在调试时工作
- 我们是否有任何通用函数来检查页面是否已完全加载到硒中
溶液
有效的方法是将 WebDriverWait 与预期条件一起诱导到:
- 元素的存在
- 元素的可见性
- 元素的可交互性
您可以在以下位置找到一些相关的讨论:
- 硒:硒如何识别可见或不可见的元素?它有可能在 DOM 中加载但不在 UI 上呈现吗?
- WebDriverWait 未按预期工作
要爬网的多个线程
WebDriver 不是线程安全的。话虽如此,如果可以序列化对基础驱动程序实例的访问,则可以在多个线程中共享引用。这是不可取的。但是,您始终可以为每个线程实例化一个 WebDriver 实例。
理想情况下,线程安全的问题不在于您的代码,而在于实际的浏览器绑定。他们都假设一次只有一个命令(例如,像真实用户一样(。但另一方面,您始终可以为每个线程实例化一个WebDriver实例,这将启动多个浏览选项卡/窗口。到目前为止,您的程序似乎很完美。
现在,不同的线程可以在同一个Web 驱动程序上运行,但测试结果将不是您所期望的。背后的原因是,当您使用多线程在不同的选项卡/窗口上运行不同的测试时,需要一点线程安全编码,否则您将执行的操作(如click()
或send_keys()
(将转到当前具有焦点的打开的选项卡/窗口,无论您期望运行的线程如何。这实质上意味着所有测试将同时在具有焦点但不在预期选项卡/窗口上的同一选项卡/窗口上运行。
在代码中,您检查readyState
,如果值未complete
,您只需sleep
一秒钟并继续执行后续步骤。这是代码,使用WebDriverWait
等待 10 秒。或者你可以使用简单的 for 循环:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(d -> ((JavascriptExecutor) d).executeScript("return document.readyState !== 'loading'"));
或与interactive
wait.until(d -> ((JavascriptExecutor) d).executeScript("return (document.readyState === 'complete' || document.readyState === 'interactive')"));
public static void processing(){
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}`enter code here`