【问题标题】:XPath $x() function returns array even if the index's specified即使指定了索引,XPath $x() 函数也会返回数组
【发布时间】:2021-03-09 22:07:24
【问题描述】:

我正在尝试选择包含"month-table_col"div 标记(按月份选择)。

...
<div class="month-table">
    <div class="month-table_row">
        <div class="month-table_col">Jan</div>
        <div class="month-table_col">Feb</div>
        <div class="month-table_col">Mar</div>
    </div>
    <div class="month-table_row">
        <div class="month-table_col">Apr</div>
        <div class="month-table_col">May</div>
        <div class="month-table_col">Jun</div>
    </div>
    <div class="month-table_row">
        <div class="month-table_col">Jul</div>
        <div class="month-table_col">Aug</div>
        <div class="month-table_col">Sep</div>
    </div>
    <div class="month-table_row">
        <div class="month-table_col">Oct</div>
        <div class="month-table_col">Nov</div>
        <div class="month-table_col">Dec</div>
    </div>
</div>
...

这里是用于指定div 标记的XPath 代码,例如,选择具有11 月值的div 标记。

//div[contains(@class, 'month-table_col') and contains(text(), 'Nov')]

在 Google Chrome 控制台中运行以下命令后,

$x("//div[contains(@class, 'month-table_col') and contains(text(), 'Nov')]")

结果:它返回一个包含这样一个元素的数组

[div.month-table_col]
   0: div.month-table_col
   lastIndex:(...)
   lastItem:(...)
   length: 1
   __proto__:Array(0)

即使我尝试指定索引为 1,它返回的结果与上图相同

$x("//div[contains(@class, 'month-table_col') and contains(text(), 'Nov')][1]")

返回的结果是正确的,但是如果无论如何我可以将元素作为标签,而不是数组结果。

预期结果:

<div class="month-table_col">Nov</div>

【问题讨论】:

    标签: html css xml xpath web-scraping


    【解决方案1】:

    Chrome DevTools XPath console function$x() 始终返回一个数组,即使选择了单个节点,即使没有选择任何节点。

    然后您可以使用 JavaScript 索引来提取任何给定的数组元素。如果 XPath 的结果是单个节点,则附加 [0] 以从返回的数组中获取该节点:

    $x("//div[contains(@class, 'month-table_col') and contains(text(), 'Nov')]")[0]
    

    提醒: XPath 节点集和序列是从 1 开始的; JavaScript 数组是从 0 开始的。

    【讨论】:

      【解决方案2】:

      首先,我认为您还没有理解 contains() 在 XPath 中的作用。我认为您想要 @class = 'month-table_col' 而不是 contains(@class, 'month-table_col') - contains() 搜索匹配的子字符串。同样,contains(text(), 'Nov') 可能应该只是 .='Nov'。 (如果可以的话,最好比较元素的字符串值,而不是寻找子文本节点)。

      但这不是你的问题:你的问题是'//'与'[]'的运算符优先级。表达式//A[1] 的意思是“对于文档中的每个节点,选择它的第一个A 子元素,如果它有一个”。您希望 (//A)[1][1] 谓词应用于最终结果,而不是单独应用于每个 child::A 选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-18
        • 2020-01-12
        • 1970-01-01
        • 2021-10-23
        • 2019-09-12
        • 1970-01-01
        • 2019-04-03
        • 1970-01-01
        相关资源
        最近更新 更多