【问题标题】:lxml truncates text that contains 'less than' characterlxml 截断包含“小于”字符的文本
【发布时间】:2012-12-19 17:04:46
【问题描述】:
>>> s = '<div> < 20 </div>'
>>> import lxml.html
>>> tree = lxml.html.fromstring(s)
>>> lxml.etree.tostring(tree)
'<div> </div>'

有人知道解决方法吗?

【问题讨论】:

  • 这是破html,可惜lxml不能优雅处理。这种类型的 html 在野外很常见。

标签: python html-parsing lxml


【解决方案1】:

您的&amp;lt; 实际上应该是&amp;lt;,因为&amp;lt; 有点像html 中的“保留字符”。那么它应该可以工作了。

【讨论】:

  • 你想要的在这里没有任何特别的意义。您的标记格式不正确。没有 XML 解析器必须猜测修复垃圾标记。所以修复你的标记first
  • 你的否定语气无关紧要。我正在抓取第 3 部分 html 页面,需要按原样解析它。我给出的例子只是为了演示这个问题。
【解决方案2】:

您的 HTML 输入已损坏; &amp;lt; 左尖括号应该被编码为 &amp;lt; 。来自lxml documentation解析损坏的HTML:

对解析损坏的 HTML 的支持完全取决于 libxml2 的恢复算法。如果您发现文档严重损坏以至于解析器无法处理它们,这不是 lxml 的错。也不能保证生成的树将包含原始文档中的所有数据。解析器在努力继续解析时可能不得不丢弃严重损坏的部分。尤其是放错位置的元标记可能会受到此影响,这可能会导致编码问题。

换句话说,你可以从这些文档中获取什么,lxml 处理损坏的 HTML 的方式是不可配置的。

可以尝试的一件事是使用不同的 HTML 解析器。请尝试BeautifulSoup,它的 HTML 处理功能可能会为您提供该文档的不同版本,从而为您提供所需的内容。 BeautifulSoup 可以重用不同的解析器后端,包括lxmlhtml5lib,因此它会给你更多的灵活性。

html5lib 解析器确实为您提供了 &amp;lt; 字符(转换为 &amp;lt; 转义):

>>> BeautifulSoup("<div> < 20 </div>", "html5lib")
<html><head></head><body><div> &lt; 20 </div></body></html>

【讨论】:

  • 呃,好久没做html的东西了,忘了&amp;lt;后面那个分号了:)
  • 您的回答很棒。您关于将 BS 与 html5lib 一起使用的建议解决了这个问题。谢谢你。对于那些投反对票的人——我认为他们不理解问题所在。
  • 既然您已经在使用lxml,值得指出的是,它有一个html5parser,它遵循w3c 推荐的解析方法(理论上是您的浏览器使用的解析方法)。
猜你喜欢
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 2015-07-06
  • 2014-01-24
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多