硒如何管理等待页面加载?

时间:2020-02-04 12:40:21

标签: selenium selenium-webdriver webdriver selenium-chromedriver

我正在开发网络爬虫一段时间,对我来说,最常见的问题是等待页面完全加载,包括请求,框架,脚本。我的意思是完全完成。

我使用了几种方法来解决它,但是当我使用多个线程来爬网网站时,总是会遇到这种问题。驱动程序会自行打开,浏览URL,不等待,再浏览下一个URL。

我的尝试是:

enter code here def register(request):
if request.method == 'POST':
    form = UserRegisterForm(request.POST)
    if form.is_valid():
        form.save()
        username = form.cleaned_data.get('username')
        messages.success(request, f'Your account has been created! You are now able to login')
        return redirect('login')
enter code here

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath));

当我运行单线程代码时,页面没有问题,但是,当我使用多线程时,这变成了一场噩梦。网络无法像单线程那样处理网页,这就是为什么我需要等待一段时间的原因。我正在寻找确切的解决方案。是否有任何进度侦听器或类似的东西?

我在等你的建议。

类似的问题:

Selenium -- How to wait until page is completely loaded

3 个答案:

答案 0 :(得分:1)

在代码中,您检查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')"));

答案 1 :(得分:1)

等待document.readyState成为complete并不是确保存在可见性交互性< / em>的元素。

因此,功能:

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);
    }
}

将是纯开销。

您可以在以下位置找到一些相关的讨论


解决方案

有效的方法是在以下两个方面促使WebDriverWaitExpectedConditions不一致:

  • 元素的存在
  • 元素的可见性
  • 元素的交互性

您可以在以下位置找到一些相关的讨论


要爬网的线程不止一个

WebDriver is not thread-safe。话虽如此,如果您可以序列化对底层驱动程序实例的访问,则可以在多个线程中共享一个引用。不建议这样做。但是,您始终可以为每个线程实例化一个WebDriver实例。

理想情况下,线程安全的问题不在您的代码中,而是在实际的浏览器绑定中。他们都假设一次只能有一个命令(例如,像真实用户一样)。但另一方面,您始终可以为每个线程实例化一个 WebDriver 实例,这将启动多个浏览选项卡/窗口。到目前为止,您的程序似乎是完美的。

现在,可以在相同的 Webdriver 上运行不同的线程,但是测试结果将不是您期望的。背后的原因是,当您使用多线程在不同的选项卡/窗口上运行不同的测试时,需要一些线程安全编码,否则您将执行的操作类似click()send_keys()到当前具有焦点的打开的选项卡/窗口,而与您希望运行的 thread 无关。从本质上讲,这意味着所有测试将同时在具有焦点但在目标选项卡/窗口上没有的同一选项卡/窗口上运行。

答案 2 :(得分:0)

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`