xpath表达式怎么写?

How to write the xpath expression?

text = '''\
<html>
    <body>
        <p><strong>test</strong>TEXT A B </p>
        <p><strong>test</strong>TEXT A </p>
        <p><strong>test</strong>TEXT B </p>
        <p><strong>ok</strong>TEXT A B </p>
        <p>TEXT A B </p>
    <body>
</html>'''
import lxml.html
root = lxml.html.fromstring(text)

html-text中有3个p节点,我想根据需要提取<p><strong>test</strong>TEXT A B </p>

特点是:

1.the p 元素的文本值包含 AB.
2.the p 的子元素 strong 的文本值为 test

node = root.xpath('.//p[contains(text(),"A") and contains(text(),"B")]')

上面的表达式将提取三个节点,我用xpath试试:

node = root.xpath('.//p[/strong(contains(text(),"test")) and contains(text(),"A") and contains(text(),"B")]')

xpath中的无效表达式,如何写出正确的格式?

根据您的要求,正确的 XPath 表达式是

//p[contains(., 'A') and contains(., 'B') and strong/text() = 'test']"

Python输出

>>> root.xpath("//p[contains(., 'A') and contains(., 'B') and strong/text() = 'test']")
[<Element p at 0x1075031b0>]

你提出的方法有问题

您的第一个解决方案不包括所有条件(缺少 strong 的文本内容),而第二个解决方案包括 strong()(您可能是指 strong[])。

您提出的第二个方法只需稍作修改即可得到相同的输出:

>>>> root.xpath('//p[strong[contains(text(),"test")] and contains(text(),"A") and contains(text(),"B")]')
[<Element p at 0x1075031b0>]

我上面的解决方案的不同之处在于我测试字符串值 .,而你的解决方案有 text().

试试 XPath 以外的解决方案,您可能也会喜欢它。

from simplified_scrapy import SimplifiedDoc
html = '''<html>
    <body>
        <p><strong>test</strong>TEXT A B </p>
        <p><strong>test</strong>TEXT A </p>
        <p><strong>test</strong>TEXT B </p>
        <p><strong>ok</strong>TEXT A B </p>
        <p>TEXT A B </p>
    <body>
</html>'''
doc = SimplifiedDoc(html)
ps = doc.selects('p').contains(['<strong>test</strong>','A','B'])
print (ps)

结果:

[{'tag': 'p', 'html': '<strong>test</strong>TEXT A B '}]

您也可以试试下面的代码,看看输出的是什么。

print (doc.selects('p').containsOr(['<strong>test</strong>','<strong>ok</strong>']))
print (doc.selects('p').notContains(['<strong>test</strong>','<strong>ok</strong>']))