Python:使用`lxml.html`将HTML内容注入标签

Posted

技术标签:

【中文标题】Python:使用`lxml.html`将HTML内容注入标签【英文标题】:Python: Injecting HTML content into a tag using `lxml.html` 【发布时间】:2011-10-25 06:00:42 【问题描述】:

我正在使用 lxml.html 库来解析 HTML 文档。

我找到了一个特定的标签,我称之为content_tag,我想更改它的内容(即<div></div>之间的文本),新内容是一个包含一些html的字符串,说它是'Hello <b>world!</b>'

我该怎么做?我试过content_tag.text = 'Hello <b>world!</b>',但它转义了所有的html标签,用<等替换<

我想注入文本而不转义任何 HTML。我该怎么做?

【问题讨论】:

nice 的方式,因为您真的想修改 DOM 结构,所以为 world 添加一个新的子节点。 【参考方案1】:

这是一种方式:

#!/usr/bin/env python2.6
from lxml.html import fromstring, tostring
from lxml.html import builder as E
fragment = """\
<div id="outer">
  <div id="inner">This is div.</div>
</div>"""

div = fromstring(fragment)
print tostring(div)
# <div id="outer">
#   <div id="inner">This is div.</div>
# </div>
div.replace(div.get_element_by_id('inner'), E.DIV('Hello ', E.B('world!')))
print tostring(div)
# <div id="outer">
#   <div>Hello <b>world!</b></div></div>

另请参阅:http://lxml.de/lxmlhtml.html#creating-html-with-the-e-factory

编辑:所以,我应该早点承认我对 lxml 不是很熟悉。我简要查看了文档和源代码,但没有找到干净的解决方案。也许,更熟悉的人会停下来,让我们俩直截了当。

与此同时,这似乎可行,但没有经过很好的测试:

import lxml.html
content_tag = lxml.html.fromstring('<div>Goodbye.</div>')
content_tag.text = '' # assumes only text to start
for elem in lxml.html.fragments_fromstring('Hello <b>world!</b>'):
    if type(elem) == str: #but, only the first?
        content_tag.text += elem
    else:
        content_tag.append(elem)
print lxml.html.tostring(content_tag)

再次编辑:此版本删除了文本和子项

somehtml = 'Hello <b>world!</b>'
# purge element contents
content_tag.text = ''
for child in content_tag.getchildren():
    content_tag.remove(child)

fragments = lxml.html.fragments_fromstring(somehtml)
if type(fragments[0]) == str:
    content_tag.text = fragments.pop(0)
content_tag.extend(fragments)

【讨论】:

这种方式对我不起作用,原因有两个:(1)我不想替换标签,我想替换标签的内容和(2)html段我要注入的已经是文本形式了,我不想用E构建它。【参考方案2】:

假设 content_tag 没有任何子元素,你可以这样做:

from lxml import html
from lxml.html.builder import B

...

content_tag.text = 'Hello '
content_tag.append(B('world!'))
print html.tostring(content_tag)

【讨论】:

没有帮助——我的 HTML 文本事先不知道,我无法在代码中将其构造为 HTML 结构。 啊,但你没有在你的问题中指定这一点(“事先不知道”部分)。 mwalsh 的编辑答案看起来不错,应该适用于任意 html。【参考方案3】:

经过一番折腾,我找到了这个解决方案:

fragments = lxml.html.fragments_fromstring(<string with tags to inject>)
last = None

for frag in fragments:
  if isinstance(frag, lxml.etree._Element):
    content_tag.append(frag)
    last = frag
  else:
    if last:
      last.tail = frag
    else:
      content_tag.text = frag

【讨论】:

以上是关于Python:使用`lxml.html`将HTML内容注入标签的主要内容,如果未能解决你的问题,请参考以下文章

python,lxml以及如何从子集中获取html代码

python怎么安装lxml html 解析器

Python:在 lxml.cssselect 中使用的 CSS 选择器

python lxml.html.soupparser.fromstring 引发恼人的警告

Python BeautifulSoup 相当于 lxml make_links_absolute

lxml(或lxml.html):打印树结构