Xpath python在特定文本后查找节点

时间:2011-08-25 10:40:25

标签: python html parsing xpath

以下是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 :(得分: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)]

你可以找到很多有关这种方法的资源,很多答案都在这里(也请查看我的答案)。我认为理解如何并不难实现这个公式,难以理解何时必须应用它。

formul的积分转到@Michael Key。只需google it a bit

我的表达式已扩展为使用其他谓词来处理您的特定情况,并使用附加表达式统一(|)以处理最后的 h2

答案 1 :(得分:0)

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

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

我不知道Python的任何XPath 2.0实现。所以这可能行不通。但也许你可以根据自己的需要改变条件。