等待内容在 Selenium 中可用

动态网页的一个常见问题是,即使整个页面已加载,因此 Selenium 中的 get() 方法已返回,但仍然可能有我们需要稍后访问的内容,因为该页面有未完成的 Ajax 请求 仍待完成。 一个例子是需要单击一个按钮,但在加载后所有数据都异步加载到页面后,该按钮才会启用。

以以下页面为例:http://the-internet.herokuapp.com/dynamic_loading/2. 该页面加载速度非常快,并向我们展示了一个 “开始” 按钮:

image 2024 01 29 16 45 35 386

按下按钮时,我们会看到一个持续五秒钟的进度条:

image 2024 01 29 16 45 55 548

完成后,我们会看到 Hello World!

image 2024 01 29 16 46 16 368

现在假设我们想抓取这个页面以获取仅在按下按钮后和等待后才暴露的内容? 我们如何做到这一点?

如何做

我们可以使用 Selenium 来做到这一点。 我们将使用 Selenium 的两个功能。 第一个是单击页面元素的能力。 第二个是能够等待具有特定 ID 的元素在页面上可用。

  1. 首先,我们获取按钮并单击它。 该按钮的 HTML 如下:

    <div id='start'>
        <button>Start</button>
    </div>
  2. 按下按钮并完成加载后,以下 HTML 将添加到文档中:

    <div id='finish'>
        <h4>Hello World!"</h4>
    </div>
  3. 我们将使用 Selenium 驱动程序找到 “开始” 按钮,单击它,然后等待 ID 为 “finish” 的 div 可用。 然后我们获取该元素并返回所包含的 <h4> 标记中的文本。

您可以通过运行 06/03_press_and_wait.py 来尝试此操作。 其输出如下:

clicked
Hello World!

现在让我们看看它是如何工作的。

工作原理

让我们分步解释:

  1. 我们首先从 Selenium 导入所需的项目:

    from selenium import webdriver
    from selenium.webdriver.support import ui
  2. 现在我们加载驱动程序和页面:

    driver = webdriver.PhantomJS()
    driver.get("http://the-internet.herokuapp.com/dynamic_loading/2")
  3. 页面加载后,我们可以检索按钮:

    button = driver.find_element_by_xpath("//*/div[@id='start']/button")
  4. 然后我们可以点击按钮:

    button.click()
    print("clicked")
  5. 接下来我们创建一个 WebDriverWait 对象:

    wait = ui.WebDriverWait(driver, 10)
  6. 通过这个对象,我们可以请求 Selenium 的 UI 等待某些事件。 这还设置了 10 秒的最长等待时间。 现在使用这个,我们可以等到满足一个标准; 可以使用以下 XPath 来识别元素:

    wait.until(lambda driver: driver.find_element_by_xpath("//*/div[@id='finish']"))
  7. 完成后,我们可以检索 h4 元素并获取其封闭文本:

    finish_element=driver.find_element_by_xpath("//*/div[@id='finish']/h4")
    print(finish_element.text)