出于某些抓取目的,我正在测试 selenium + chrome
与 requests + lxml
。我有兴趣获取一些短信。
当使用selenium + chrome
时,我可以这样做:
element = self.driver.find_element_by_xpath(xpath)
return element.text.strip()
它将返回与xpath
选择器匹配的元素的文本。文本将按照网站上的显示方式显示,这意味着如果测试本身为小写,但它具有 text-transform: uppercase
,则该代码段的输出将是大写文本.
如果我对 lxml 执行相同的操作,如下所示:
elements = self.get_xpath_elements(xpath)
text = ''.join(elements[0].itertext()).strip()
它将返回 HTML 中显示的文本,而不考虑文本的样式。
有没有办法让 lxml 的行为与 selenium + chrome 相同?
最佳答案
简短的回答 - 这取决于。在 selenium 案例中您看到的是 html,它是从浏览器处理后的形式。它们的主要目的(除了可视化内容之外,对我们来说,仅仅是人类:))是解析 html、css 和 js,并将后两者应用于前者。因此,得到的结果是应用了它们的(JS 和 CSS)规则集并且有效(例如,在您的示例中是小写字母)。
lxml 或任何其他 XML 解析库不会这样做 - 它们独立地解析 XML/HTML,它们不知道(或不关心)像 css 这样的修改系统(它们关心关于 XSLT,但这是一个非常不同的主题)。因此,您看到的结果是以“vanilla”形式编写的 HTML,它引用的任何 css 规则都不会应用。
<小时/>我说“这取决于”,因为您可以在浏览器渲染/操作 HTML 时将其加载到 lxml(或任何其他解析器)中。您可以通过self.driver.page_source
访问它。 webdriver 对象的属性。
它保存的 html 格式与您在浏览器的“检查元素” View 中看到的格式相同 - 具有任何 JS 和 CSS 结构(和内容)操作。然而,我不认为正是这种情况 - 文本的小写字母将被应用;我认为它处于渲染阶段 - 例如该值在源中是“原样”,但浏览器以不同的方式显示它。遗憾的是我没有在电脑前亲自尝试一下。
<小时/>我向您推荐的另一种方法是尝试这个库 - requests-html 。它是 requests
的一种变体,专注于 HTML 解析(khm,只需 - 看看它的名字:D)。它支持 javascript - 以及作为“副作用”CSS - 解析原始 HTML,并且可能会为您解决问题。
后者是通过 response_object.html.render()
完成的。
关于python - 从元素中检索文本时,lxml 不考虑 css 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54155735/