[英]How to get the raw text from lxml element with Python
我想從根元素中獲取以下內聯文本字符串。
from lxml import etree
root = root = etree.fromstring(
'''<p>
text-first
<span>
Child 1
</span>
text-middle
<span>
Child 2
</span>
text-last
</p>''')
root.text
僅返回“文本優先”,包括換行符
>>> build_text_list = etree.XPath("//text()")
>>> texts = build_text_list(root)
>>>
>>> texts
['\n text-first\n ', '\n Child 1\n ', '\n text-middle\n ', '\n Child 2\n ', '\n text-last\n']
>>>
>>> for t in texts:
... print t
... print t.__dict__
...
text-first
{'_parent': <Element p at 0x10140f638>, 'is_attribute': False, 'attrname': None, 'is_text': True, 'is_tail': False}
Child 1
{'_parent': <Element span at 0x10140be18>, 'is_attribute': False, 'attrname': None, 'is_text': True, 'is_tail': False}
text-middle
{'_parent': <Element span at 0x10140be18>, 'is_attribute': False, 'attrname': None, 'is_text': False, 'is_tail': True}
Child 2
{'_parent': <Element span at 0x10140be60>, 'is_attribute': False, 'attrname': None, 'is_text': True, 'is_tail': False}
text-last
{'_parent': <Element span at 0x10140be60>, 'is_attribute': False, 'attrname': None, 'is_text': False, 'is_tail': True}
>>>
>>> root.xpath("./p/following-sibling::text()") # following https://stackoverflow.com/a/39832753/1677041
[]
那么,我怎樣才能從中獲得text-first/middle/last
的部分?
etree 完全有能力做到這一點:
from lxml import etree
root: etree.Element = etree.fromstring(
'''<p>
text-first
<span>
Child 1
</span>
text-middle
<span>
Child 2
</span>
text-last
</p>''')
print(
root.text,
root[0].tail,
root[1].tail,
)
所有元素都是其子元素的列表,因此這里的索引是指 2 個<span>
元素。 任何元素的 tail 屬性都包含該元素之后的文本。
它當然會包含換行符,因此您可能想要 strip() 結果: root.text.strip()
您最初的猜測, //text()
表示:select 所有文本節點,無論它們在文檔中的哪個位置。 你真正想要的 select 是文本節點,如果它們是p
的直接子節點,或者如果它們不是span
的子節點。
給定您顯示的輸入文檔,最准確的答案是/p/text()
:
>>> root = etree.fromstring(
'''<p>
text-first
<span>
Child 1
</span>
text-middle
<span>
Child 2
</span>
text-last
</p>''')
>>> etree.XPath("/p/text()")(root)
['\n text-first\n ', '\n text-middle\n ', '\n text-last\n']
您自己的解決方案child::text()
表示:select 文本節點,如果它們是當前上下文節點的子節點。 它之所以有效,是因為 XPath 表達式在這種情況下使用根元素p
作為上下文進行評估。 這就是為什么簡單的text()
也可以工作的原因。
>>> etree.XPath("text()")(root)
['\n text-first\n ', '\n text-middle\n ', '\n text-last\n']
我的錯, xpath
救了我。
>>> root.xpath('child::text()')
['\n text-first\n ', '\n text-middle\n ', '\n text-last\n']
print(root.xpath('normalize-space(//*)'))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.