Splinter 或 Selenium:我们可以在单击按钮后获取当前的 html 页面吗?

Posted

技术标签:

【中文标题】Splinter 或 Selenium:我们可以在单击按钮后获取当前的 html 页面吗?【英文标题】:Splinter or Selenium: Can we get current html page after clicking a button? 【发布时间】:2015-01-04 18:12:53 【问题描述】:

我正在尝试抓取网站“http://everydayhealth.com”。但是,我发现页面会动态呈现。因此,当我单击“更多”按钮时,将显示一些新消息。但是,使用 splinter 单击按钮不会让“browser.html”自动更改为当前的 html 内容。有没有办法让它获得最新的 html 源代码,使用 splinter 或 selenium?我在 splinter 中的代码如下:

import requests
from bs4 import BeautifulSoup
from splinter import Browser

browser = Browser()
browser.visit('http://everydayhealth.com')
browser.click_link_by_text("More")

print(browser.html)

根据@Louis 的回答,我将程序改写如下:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()
driver.get("http://www.everydayhealth.com")
more_xpath = '//a[@class="btn-more"]'
more_btn = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(more_xpath))
more_btn.click()
more_news_xpath = '(//a[@href="http://www.everydayhealth.com/recipe-rehab/5-herbs-and-spices-to-intensify-flavor.aspx"])[2]'
WebDriverWait(driver, 5).until(lambda driver: driver.find_element_by_xpath(more_news_xpath))

print(driver.execute_script("return document.documentElement.outerHTML;"))
driver.quit()

但是,在输出文本中,我仍然找不到更新页面中的文本。例如,当我搜索“Milk Your Friend or Foe?”时,它仍然没有返回任何内容。有什么问题?

【问题讨论】:

如何检查 HTML 中没有变化?例如,我在打印的 html 中看到 5 Herbs and Spices That Boost Your Health 文本,并且在单击 More 按钮后加载。 @alecxe 感谢您的回复。我想我检查它的方式和你检查它的方法一样。您在打印的 html 中找到“5 种促进健康的草药和香料”的原因是因为这篇文章恰好显示在网页最顶部的缩略图中。如果您在单击按钮后检查显示的任何其他标题,例如“牛奶是您的朋友还是敌人?”,您不会找到它。 【参考方案1】:

使用 Selenium,假设 driver 是您初始化的 WebDriver 对象,这将为您提供与您进行调用时 DOM 状态相对应的 HTML:

driver.execute_script("return document.documentElement.outerHTML;")

返回值是一个字符串,所以你可以这样做:

print(driver.execute_script("return document.documentElement.outerHTML;"))

【讨论】:

感谢您的回复。你能看看我更新的问题吗?我按照您的指示进行操作,但输出文本仍然没有新生成的 html。 您遇到的问题是您在页面完成更新之前获取了 HTML。知道您有时间问题的一个非常简单的方法是使用time.sleep(...) 并输入您知道足以发生更新的任意秒数。如果它适用于睡眠,那么您知道您有时间问题。你可能没有等待正确的事情。看起来更多新闻按钮在添加文章之前被放回页面。这是一个与仅仅获取动态 HTML 截然不同的问题。所以我建议... ... 让这个问题保持原样,研究您正在使用的网页,看看您实际上应该等待什么,也许阅读一些关于在 Selenium 中等待的 SO 问题,然后如果您仍然需要帮助,请专门发布一个关于等待的新问题。 我应该在第一条评论中提到我确实下载了您的代码并在这里尝试过,这绝对是一个时间问题。当我在 print 之前添加 import time; time.sleep(5) 时,它起作用了。 哇,插入语句“time.sleep(5)”后它就可以工作了。感谢您的提示!此外,是否有更智能的方式来等待页面完全加载而不是静态等待?实际上,我添加了句子“WebDriverWait(driver, 5).until(lambda driver: driver.find_element_by_xpath(more_news_xpath))”以检查更新页面中是否显示了一些新元素,但它似乎无法正常工作。谢谢。【参考方案2】:

当我将 Selenium 用于此类任务时,我知道 browser.page_source 确实会更新。

【讨论】:

以上是关于Splinter 或 Selenium:我们可以在单击按钮后获取当前的 html 页面吗?的主要内容,如果未能解决你的问题,请参考以下文章

在Python中处理JavaScript事件

是否有适用于Behave的Python无头浏览器,而不使用Selenium或真实的浏览器

教程丨基于Python爬虫技术的抢票程序及其实现

微软又出现好玩的了,Python 录制自动化操作,自动生成代码

尝鲜~ 微软又出现好玩的了,Python 录制自动化操作,自动生成代码

Splinter学习--初探3,两种方式登录QQ邮箱