lxml使用元素移动文本

时间:2013-07-17 22:24:00

标签: python html lxml

我有一个用div包装图片的问题。

from lxml.html import fromstring
from lxml import etree

tree = fromstring('<img src="/img.png"/> some text')
div = etree.Element('div')
div.insert(0, tree.find('img'))
tree.insert(0, div)
print etree.tostring(tree)

<span><div><img src="/img.png"/> some text</div></span>

为什么它会添加一个范围,如何在没有文字的情况下将图像包裹起来?

2 个答案:

答案 0 :(得分:3)

因为lxml实际上是一个xml解析器。它有一些宽容的解析规则,允许它解析html(lxml.html部分),但它将在内部始终构建一个有效的树。

'<img src="/img.png"/> some text'不是树,因为它没有单个根元素,有img元素和文本节点。为了能够在内部存储此snipplet,lxml需要将其包装在合适的标记中。如果你单独给它一个字符串,它会将它包装在p标签中。早期的版本只包含html标签中的所有内容,这可能会导致更多的混淆。

你也可以使用html.fragment_fromstring,在这种情况下不会添加标签,但会因为片段无效而引发错误。

至于文本为什么坚持img标签:这就是lxml如何存储文本。举个例子:

>>> p = html.fromstring("<p>spam<br />eggs</p>")
>>> br = p.find("br")
>>> p.text
'spam'
>>> br.text       # empty
>>> br.tail       # this is where text that comes after a tag is stored
'eggs'

因此,通过移动标签,您也可以移动它的尾部。

答案 1 :(得分:1)

lxml.html是一个更友善,更温和的xml处理器,试图理解无效的xml。你传入的刺痛只是从xml角度来看是垃圾,但是lxml.html将它包装在span元素中以使其再次有效。如果你不想要lxml.html guestimating,请坚持使用lxml.etree.fromstring()。该版本将拒绝该字符串。