我想从根元素中获取以下内联文本字符串。
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
部分呢?
有什么想法吗?谢谢!
答案 0 :(得分:1)
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属性都在该元素之后直接包含文本。
它当然将包括换行符,因此您可能要剥离()结果:root.text.strip()
答案 1 :(得分:1)
您最初的猜测,<class 'str'> ФАО ЦЕСНАБАНК г. Степногорск
<class 'str'> ежемесячно
<class 'str'> Стандартный
<class 'pandas._libs.tslibs.timestamps.Timestamp'> 2015-06-01 00:00:00
<class 'pandas._libs.tslibs.timestamps.Timestamp'> 2015-05-06 00:00:00
<class 'pandas._libs.tslibs.timestamps.Timestamp'> 2017-05-06 00:00:00
<class 'numpy.float64'> 220000.0
<class 'numpy.int64'> 25
<class 'numpy.float64'> 37.5
<class 'numpy.int64'> 0
<class 'str'> Акмолинская Область
<class 'str'> Собственное
<class 'str'> Казахстан
<class 'str'> Потребительские цели
<class 'pandas._libs.tslibs.timestamps.Timestamp'> 2015-05-06 00:00:00
<class 'numpy.int64'> 24
<class 'numpy.float64'> 6.0
<class 'pandas._libs.tslibs.timestamps.Timestamp'> 2015-05-04 00:00:00
<class 'numpy.float64'> 1.0
<class 'str'> Взнос наличными деньгами
<class 'str'> От 1 года до 5 лет
<class 'numpy.float64'> 1.0
<class 'numpy.float64'> 33862.11
的意思是:选择所有文本节点,无论它们在文档中的什么位置。如果文本节点是//text()
的直接子代,或者不是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()
作为上下文来评估XPath表达式。这就是为什么p
也可以工作的原因。
text()
答案 2 :(得分:0)
我的坏人,xpath
最终救了我。
>>> root.xpath('child::text()')
['\n text-first\n ', '\n text-middle\n ', '\n text-last\n']
答案 3 :(得分:0)
print(root.xpath('normalize-space(//*)'))