由于各种原因,我试图从切换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'
Run Code Online (Sandbox Code Playgroud)
这是有道理的.我的问题是,处理这个问题的最佳方法是什么.我有很多代码需要HtmlElements,所以我认为最好的解决方案是转换为那些.我不确定这是否可行.
一个可怕的解决方案看起来像这样:
from lxml.html import fromstring, tostring
from lxml.html import html5parser
e = html5parser.fromstring(text)
html_element = fromstring(tostring(e))
Run Code Online (Sandbox Code Playgroud)
显然,这是非常强大的力量,但确实有效.我能够得到一个被html5parser解析的HtmlElement,这就是我所追求的.
另一个选择是找出如何进行我依赖的rewrite_links和xpath查询,但是_Element似乎没有那个函数(这也是有意义的!)
一种比暴力方式更少占用 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))
Run Code Online (Sandbox Code Playgroud)
将输出:
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>'
Run Code Online (Sandbox Code Playgroud)
因此,“body”等属性和“rewrite_links”等方法都可以在这种情况下使用。
| 归档时间: |
|
| 查看次数: |
504 次 |
| 最近记录: |