如何在lxml中查找元素的直接子元素

问题描述 投票:0回答:3
python xpath lxml
3个回答
2
投票

我不确定,但你的问题似乎出在 HTML 本身:请注意 有几个标签省略情况适用于

p
节点,因此段落的结束标签

<div class='thread'>
    <p>first
        <p>second</p>
    </p>
</div>

简单地被解析器忽略,并且两个节点都被标识为兄弟节点,但不是父节点和子节点,例如

<div class='thread'>
    <p>first
    <p>second
</div>

所以 XPath

//div[@class="thread"]/p
会返回两个段落

您只需将

p
标签替换为
div
标签,您就会看到不同的行为:

<div class='thread'>
    <div>first
        <div>second</div>
    </div>
</div>

这里

//div[@class="thread"]/div
将仅返回第一个节点

如果我的假设不正确,请纠正我


1
投票

尝试这个 XPath 表达式:

//p[parent::div[@class='thread']]

或者用完整的Python表达式:

THREAD.xpath("//p[parent::div[@class='thread']]")

另一种(逆)方法是这个 XPath 表达式:

div[@class='thread']/child::p"

使用直接

child::
轴并且仅选择直接子节点。

总结:
两个表达式中哪一个更快取决于 XPath 编译器。

child::
是默认轴,如果没有给出其他轴则使用。


仅供参考:XPath 计数从 1 开始,并且 不是 0
因此,关于您的 XML 示例,以下表达式

count(//div[@class='thread'][1]/child::p)

的结果是 2 - 计算

<p> <!-- 1 -->
+
<p><!-- 2 --></p>
的结果。


0
投票

你可以尝试PARENT.getchildren()

>>> root = etree.fromstring(xml)
>>> root.xpath("//div[@class='thread']")[0].getchildren()
[<Element p at 0x10b3110e0>, <Element p at 0x10b311ea8>]
© www.soinside.com 2019 - 2024. All rights reserved.