例如,html block:
<p><b>text1</b> (<span><a href="#1">asdf</a>text2</span>)</p>
我需要选择所有标签“a”,所有其余标签必须是纯文本,就像我们在浏览器中看到的一样:
result = ["text1", " (", <tag_a>, "text2", ")"]
或类似的东西。
尝试:
hxs.select('.//a|text()')
在这种情况下,它会找到所有标签“a”,但文本仅从直接子节点返回。
同时:
hxs.select('.//text()|a')
获取所有文本,但仅使用直接子项标记“a”。
更新
elements = []
for i in hxs.select('.//node()'):
try:
tag_name = i.select('name()').extract()[0]
except TypeError:
tag_name = '_text'
if tag_name == 'a':
elements.append(i)
elif tag_name == '_text':
elements.append(i.extract())
有更好的方法吗?
答案 0 :(得分:1)
在我看来,好像你正在超越XPath领域。 XPath擅长从输入中选择事物而不是构造输出。当然,它被设计用于XSLT,其中XSLT指令处理输出端。我不确定Python的等价物是什么。
答案 1 :(得分:1)
这是你要找的东西吗?
您可以使用etree.strip_tags
from lxml import etree
d = etree.HTML('<html><body><p><b>text1</b> (<span><a href="#1">asdf</a>text2</span>)</p></body></html>')
block = d.xpath('/html/body/p')[0]
# etree.strip_tags apparently takes a list of tags to strip, but it wasn't working for me
for tag in set(x.tag for x in block.iterdescendants() if x.tag != 'a'):
etree.strip_tags(block,tag)
block.xpath('./text()|a')
收率:
['text1', ' (', <Element a at fa4a48>, 'text2', ')']
答案 2 :(得分:1)
这些相对 XPath表达式:
.//text()|.//a
或者
.//node()[self::text()|self::a]
表示:来自上下文节点的所有后代文本节点或a
元素。
注意:由主机语言或XPath引擎决定是否按文档顺序排序此节点集结果。根据定义,节点集是无序的。