【问题标题】:get sub elements with xpath of lxml.html (Python)使用 lxml.html (Python) 的 xpath 获取子元素
【发布时间】:2017-05-07 18:27:32
【问题描述】:

我正在尝试使用 lxml.html 获取子元素,代码如下。

import lxml.html as LH

html = """
<ul class="news-list2">
            <li>
            <div class="txt-box">
            <p class="info">Number:<label>cewoilgas</label></p>
            </div>
            </li>

            <li>
            <div class="txt-box">
            <p class="info">Number:<label>NHYQZX</label>
            </p>
            </div>
            </li>

        <li>
            <div class="txt-box">
            <p class="info">Number:<label>energyinfo</label>
            </p>
            </div>
            </li>

        <li>
            <div class="txt-box">
            <p class="info">Number:<label>calgary_information</label>
            </p>
            </div>
            </li>

        <li>
            <div class="txt-box">
            <p class="info">Number:<label>oilgas_pro</label>
            </p>
            </div>
            </li>

</ul>
"""

获取li中的子元素:

htm = LH.fromstring(html)
for li in htm.xpath("//ul/li"):
    print li.xpath("//p/label/text()")

很好奇为什么是这样的结果

['cewoilgas', 'NHYQZX', 'energyinfo', 'calgary_information', 'oilgas_pro']
['cewoilgas', 'NHYQZX', 'energyinfo', 'calgary_information', 'oilgas_pro']
['cewoilgas', 'NHYQZX', 'energyinfo', 'calgary_information', 'oilgas_pro']
['cewoilgas', 'NHYQZX', 'energyinfo', 'calgary_information', 'oilgas_pro']
['cewoilgas', 'NHYQZX', 'energyinfo', 'calgary_information', 'oilgas_pro']

我也发现解决办法是:

htm = LH.fromstring(html)
for li in htm.xpath("//ul/li"):
    print li.xpath(".//p/label/text()")

结果是:

['cewoilgas']
['NHYQZX']
['energyinfo']
['calgary_information']
['oilgas_pro']

这应该算是lxml的一个bug吗?为什么 xpath 在子元素 (li) 下仍然匹配整个根元素 (ul)?

【问题讨论】:

    标签: python html xpath lxml


    【解决方案1】:

    不,这不是错误,而是预期的行为。如果您以// 开始您的表达式,那么无论您在树的根部还是在树的任何元素上调用它都没有关系——它将是绝对的,并且将从根部应用。

    请记住,如果在一个元素上调用 xpath() 并且您希望它相对于该元素起作用,请始终以一个指向 当前节点的点开始您的表达式。

    顺便说一句,seleniumfind_element(s)_by_xpath() 绝对(双关语)发生了同样的事情。

    【讨论】:

    • 好的,如果是这样的话。就这样接受吧……然而,这对新手来说真的很困惑……
    • 其实我觉得OP是对的。这种行为没有任何意义。如果你调用 etree.tostring(li),你会得到一个 xml 片段作为字符串,而在一个新的 xpath 表达式中使用 li 对原始的整个树起作用。这是非常不直观的。
    【解决方案2】:

    //para 选择文档根的所有 para 后代,因此 选择与上下文节点相同的文档中的所有 para 元素

    //olist/item 选择与 具有 olist 父级的上下文节点

    . 选择上下文节点

    .//para选择上下文节点的para元素后代

    您可以在XML Path Language (XPath)中找到更多示例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 2020-08-25
      相关资源
      最近更新 更多