9

由于各种原因,我试图从 切换lxml.html.fromstring()lxml.html.html5parser.document_fromstring(). 两者最大的区别是第一个返回一个lxml.html.HtmlElement,第二个返回一个lxml.etree._Element

大多数情况下这是可以的,但是当我尝试使用该_Element对象运行我的代码时,它崩溃了,说:

AttributeError: 'lxml.etree._Element' object has no attribute 'rewrite_links'

这是有道理的。我的问题是,处理这个问题的最佳方法是什么。我有很多需要 HtmlElements 的代码,所以我认为最好的解决方案是转换为那些。我不确定这是否可能。

更新

一个糟糕的解决方案如下所示:

from lxml.html import fromstring, tostring
from lxml.html import html5parser

e = html5parser.fromstring(text)
html_element = fromstring(tostring(e))

显然,这是相当蛮力的,但它确实有效。我能够得到一个由 html5parser 解析的 HtmlElement,这就是我所追求的。

另一种选择是弄清楚如何执行我所依赖的 rewrite_links 和 xpath 查询,但_Elements 似乎没有该功能(这又是有道理的!)

4

1 回答 1

0

一种 CPU 密集度低于蛮力的解决方案是基于根树创建一个几乎为空的 HtmlElement 并附加 _Element 子项。

from lxml.html import fromstring, tostring
from lxml.html import html5parser


text = "<html lang='en'><body><a href='http://localhost'>hello</body></html>"
e = html5parser.fromstring(text)

html_element = fromstring(tostring(e.getroottree()))
for child in e.getchildren():
  html_element.append(child)

print(tostring(html_element))


def rewriter(link):
  return "http://newlink.com"

html_element.rewrite_links(rewriter)
print(tostring(html_element.body)) 

将输出:

b'<html><body><html xmlns:html="http://www.w3.org/1999/xhtml" lang="en"><head></head><body><a href="http://localhost">hello</a></body></html></body><html:head xmlns:html="http://www.w3.org/1999/xhtml"></html:head><html:body xmlns:html="http://www.w3.org/1999/xhtml"><html:a href="http://localhost">hello</html:a></html:body></html>'
b'<body><html xmlns:html="http://www.w3.org/1999/xhtml" lang="en"><head></head><body><a href="http://newlink.com">hello</a></body></html></body>'

因此,像“body”这样的属性和像“rewrite_links”这样的方法都适用于这种情况。

于 2020-02-23T17:00:42.330 回答