XPath Python 找特定文本后的节点

1 投票
2 回答
1035 浏览
提问于 2025-04-17 00:19

这是HTML代码:

<div id="someid">
    <h2>Specific text 1</h2>
    <a class="hyperlinks" href="link"> link1 inside specific text 1</a>
    <a class="hyperlinks" href="link"> link2 inside specific text 1</a>
    <a class="hyperlinks" href="link"> link3 inside specific text 1</a>

    <h2>Specific text 2</h2>
    <a class="hyperlinks" href="link"> link1 inside specific text 2</a>
    <a class="hyperlinks" href="link"> link2 inside specific text 2</a>
    <a class="hyperlinks" href="link"> link3 inside specific text 2</a>
    <a class="hyperlinks" href="link"> link4 inside specific text 2</a>

    <h2>Specific text 3</h2>
    <a class="hyperlinks" href="link"> link1 inside specific text 3</a>
    <a class="hyperlinks" href="link"> link2 inside specific text 3</a>         

</div>  

我需要在每个“特定文本”下面清楚地找到链接。问题是,如果我在Python中写以下代码:

links = root.xpath("//div[@id='someid']//a")
for link in links:
    print link.attrib['href']

它会打印出所有的链接,而不管“特定文本x”是什么。可是我想要的结果是:

print "link under Specific text:"+specific+" link:"+link.attrib['href']

请给我一些建议

2 个回答

0

你可以使用 XPath 2.0 的 starts-with(s, t) 函数来创建一个匹配 h2 值的条件。

//div/h2[starts-with(text(), 'Specific text')]//a

我不知道 Python 有没有支持 XPath 2.0 的实现。所以这可能不太好用。不过,也许你可以根据自己的需求调整这个条件。

1

我觉得你需要为每个特定的 h2 文本写一个 XPath 表达式。

给定一个特定的 h2 文本,你可以通过以下方式获取它后面紧邻的 a 兄弟元素:

    //div[@id='someid']/h2[.='Specific text 1']
     /following-sibling::a[
      count( . | following-sibling::h2[1]/preceding-sibling::*)
      = count(following-sibling::h2[1]/preceding-sibling::*)
      and preceding-sibling::h2[1][.='Specific text 1']]
    |
    //div[@id='someid']/h2[.='Specific text 1' and not(following-sibling::h2[1])]
    /following-sibling::a"

第二个 //h2 选择是为了处理 h2 是最后一个的情况。

上面的表达式利用了 XPath 1.0 的交集公式:

$ns1[count(.|$ns2)=count($ns2)]

你可以找到很多关于这个方法的资源,这里在 StackOverflow 上也有很多答案(你也可以看看我的答案)。我觉得理解 如何 应用这个公式并不难,真正困难的是理解 什么时候 应该应用它。

这个公式的来源是 @Michael Key。你可以稍微 谷歌一下

我的表达式已经扩展了额外的条件,以处理你的特定情况,并且与处理最后一个 h2 的额外表达式进行了统一(|)。

撰写回答