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

Pio*_*rek 5 python xpath lxml

我找到了一个具有特定类的对象:

THREAD = TREE.find_class('thread')[0]
Run Code Online (Sandbox Code Playgroud)

现在我想获取<p>它的直接子元素的所有元素。

我试过:

THREAD.findall("p")

THREAD.xpath("//div[@class='thread']/p")
Run Code Online (Sandbox Code Playgroud)

但所有这些都返回<p>this 内的所有元素<div>,无论它<div>是否是它们最近的父元素。

我怎样才能让它发挥作用?

编辑:

示例 HTML:

<div class='thread'>
   <p> <!-- 1 -->
      <!-- Can be some others <p> objects inside, which should not be counted -->
   </p> 
   <p><!-- 2 --></p>
</div>
<div class='thread'>
   <p>[...]</p>
   <p>[...]</p>
</div>
Run Code Online (Sandbox Code Playgroud)

脚本应该找到两个对象<p>,它们是 的子对象THREAD。我应该收到两个对象的列表,在示例 HTML 的注释中标记为“1”和“2”。

编辑2:

由于人们感到困惑,还有一个澄清:

THREAD是存储在变量中的一些对象,可以是任何 html 元素。我想找到 的<p>直接子对象THREAD。这些<p>元素不能位于THREAD任何位于其内部的元素的外部或内部THREAD

zx4*_*485 1

试试这个 XPath 表达式:

//p[parent::div[@class='thread']]
Run Code Online (Sandbox Code Playgroud)

或者用完整的 Python 表达式:

THREAD.xpath("//p[parent::div[@class='thread']]")
Run Code Online (Sandbox Code Playgroud)

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

div[@class='thread']/child::p"
Run Code Online (Sandbox Code Playgroud)

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

摘要:
两个表达式中哪一个更快取决于 XPath 编译器。child::是默认轴,如果没有给出其他轴,则使用它。


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

count(//div[@class='thread'][1]/child::p)
Run Code Online (Sandbox Code Playgroud)

确实会产生值 2 - 计数<p> <!-- 1 -->+的结果<p><!-- 2 --></p>