解析HTML时为何有时需要item.text而有时需要item.text_content()

10 投票
2 回答
7441 浏览
提问于 2025-04-16 02:59

我还在学习lxml这个库。我发现有时候我用item.text无法获取到树中某个项目的文本内容。如果我使用item.text_content(),就能顺利获取到。我现在还不太明白为什么会这样。如果有任何提示,我会很感激。

好吧,我不太确定怎么提供一个例子而不让你处理一个文件:

这是我写的一些代码,试图弄清楚为什么我得不到一些我预期的文本:

theTree=html.fromstring(open(notmatched[0]).read()) 
text=[]
text_content=[]
notText=[]
hasText=[]
for each in theTree.iter():
    if each.text:
        text.append(each.text)
        hasText.append(each)   # list of elements that has text each.text is true
    text_content.append(each.text_content()) #the text for all elements 
    if each not in hasText:
        notText.append(each)

所以在我运行完这个之后,我查看

>>> len(notText)
3612
>>> notText[40]
<Element b at 26ab650>
>>> notText[40].text_content()
'(I.R.S. Employer'
>>> notText[40].text

2 个回答

5

你可能会对不同的接口感到困惑,这些接口是lxml实现的,而且它们之间不兼容。比如说,lxml.etree里的元素有一个.text属性,而来自lxml.html的元素则使用text_content这个方法(还有来自BeautifulSoup的元素,包含在lxml里,它们有一个.string属性... 有时候 [[只有当节点有一个子节点且这个子节点是字符串时...]])。

是的,lxml选择同时实现自己的接口和模仿或包含其他库,这确实让人感到困惑,但这样做有时候也挺方便的...;-)

13

根据文档text_content这个方法的作用是:

返回这个元素的文本内容,包括它的子元素的文本内容,而且不会有任何标记。

举个例子,

import lxml.html as lh
data = """<a><b><c>blah</c></b></a>"""
doc = lh.fromstring(data)
print(doc)
# <Element a at b76eb83c>

doc是一个Element对象,代表标签。这个标签后面没有直接跟着文本(在<a><b>之间),所以doc.text的值是None

print(doc.text)
# None

但是在c标签后面有文本,所以doc.text_content()的值不是None

print(doc.text_content())
# blah

另外,这里有一个关于text属性含义的清晰描述在这里。虽然它是lxml.etree.Element文档的一部分,但我认为texttail属性的含义同样适用于lxml.html.Element对象。

撰写回答