我正在尝试使用lxml和Python从网站中过滤掉文本,但格式化可能非常不规则。 (这是一个论坛。)
例如,我可能有:
<a>
<c>
<d>
MARKER some text
</d>
</c>
MARKER other text 1
<b>MARKER other text 2</b>
M<b>ARKE</b>R <e>other</e> text 3
</a>
我希望我的xpath能够回复我:
MARKER other text 1
<b>MARKER other text 2</b>
M<b>ARKE</b>R <e>other</e> text 3
换句话说,我希望能够解析嵌套文本,但也会返回带有标记的文本。
我目前拥有的是:
filter = "//text()[not(parent::d[parent::c]) and contains(., 'MARKER')]"
filtered = root.xpath(self.vote_xpath)
for i in filtered:
print(i)
其中root
是从字符串解析的元素树,它返回我:
MARKER other text 1
MARKER other text 2
这使我无法使用MARKER返回最后一个文本,并且无法保留我想要的格式。
我该如何从这里开始?
编辑: 好的,我一直在使用xpath。
//node()[not(parent::d[parent::c]) and contains(., 'MARKER')]
运行:
<a>
<c>
<d>
some text
</d>
</c>
other text 1
<b>other text 2</b>
M<b>ARKE</b>R <e>other</e> text 3
</a>
成功注册了由MARKER
代码分解的<b>
,因为node()
将整个节点传递给contains
过滤器。但是,它返回父节点整数的匹配,在这种情况下,它只返回整个<a>
节点及其所有内容。
我应该如何继续使xpath只返回匹配的部分?
答案 0 :(得分:2)
从不同的角度看待它可能会有所帮助。您的半完整解决方案专注于所需数据的父元素,但您也可以使用子路径标识符或相对路径标识符。
我得到了这个XPATH:
a/c/following-sibling::node()
要返回:
MARKER other text 1
<b>MARKER other text 2</b>
M
<b>ARKE</b>
R
<e>other</e>
text 3
虽然这不是您正在寻找的格式,但它是正确的数据,XPATH并不是真正用于格式化您的结果,所以没有太多可以在那里工作。