怎么使用lxml从这个HTML代码片段中获取文本?

本教程将介绍如何使用lxml从这个HTML代码片段中获取文本?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

怎么使用lxml从这个HTML代码片段中获取文本? 教程 第1张

问题描述

谁能解释为什么此代码段在断言中失败?

from lxml import etree

s = '<div><h2><img />XYZZY</h2></div>'

root = etree.fromstring(s)

elements = root.xpath(".//*[contains(text(),'XYZZY')]")  # Finds 1 element, as expected

for el in elements:
 assert el.text is not None

然后...怎么访问&Quot;XYZZY&Quot;并将其更改为&Quot;ZYX&Quot;?

推荐答案

谁能解释为什么此代码段在断言中失败?

因为<h2>元素的文本由lxml存储在h2元素的一个子元素中。您可以使用itertext()获取您需要的内容。

from lxml import etree
s = '<div><h2><img />XYZZY</h2></div>'
root = etree.fromstring(s)
elements = root.xpath(".//*[contains(text(),'XYZZY')]")
for el in elements:
 el_text = ''.join(el.itertext())
 assert el_text is not None
 print(el_text)

更新:进一步查看后,发现每个元素都有3个相关属性:.tag.text.tail

对于.tail属性,there is a small part in the tutorial可以解释:

<html><body>Hello<br/>World</body></html>

这里,
标记用文本括起来。这通常被称为
文档样式或混合内容的XML。元素通过其
Tail属性。它包含紧跟在元素后面的文本,
直到XML树中的下一个元素

怎么填充.tail是again explained here:

LXML将未包装在其自己的标记中的尾随文本追加为前一个标记的.tail属性。

因此我们实际上可以编写以下代码,以遍历元素树中的每个元素并找到文本XYZZY所在的位置:

from lxml import etree
s = '<div><h2><img />XYZZY</h2></div>'
root = etree.fromstring(s)

context = etree.iterwalk(root, events=("start","end"))
for action, elem in context:
 print("%s: %s : [text=%s : tail=%s]" % (action, elem.tag, elem.text, elem.tail))

输出:

start: div : [text=None : tail=None]
start: h2 : [text=None : tail=None]
start: img : [text=None : tail=XYZZY]
end: img : [text=None : tail=XYZZY]
end: h2 : [text=None : tail=None]
end: div : [text=None : tail=None]

因此它位于<img>元素的.tail属性中。

关于您的第二个问题:

然后...怎么访问&Quot;XYZZY&Quot;并将其更改为&Quot;ZYX&Quot;?

一种解决方案是只遍历元素树,检查每个元素的文本或尾部中是否有字符串,然后替换它:

#!/usr/bin/python3
from lxml import etree
s = '<div><h2><img />XYZZY</h2></div>'
root = etree.fromstring(s)

search_string = "XYZZY"
replace_string = "ZYX"

context = etree.iterwalk(root, events=("start","end"))
for action, elem in context:
 if elem.text and elem.text.strip() == search_string:
  elem.text = replace_string
 elif elem.tail and elem.tail.strip() == search_string:
  elem.tail = replace_string

print(etree.tostring(root).decode("utf-8"))

输出:

<div><h2><img/>ZYX</h2></div>

好了关于怎么使用lxml从这个HTML代码片段中获取文本?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。