ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 XPath 选择以下同级/XML 标记

我有一个 HTML 文件(来自 Newegg),它们的 HTML 组织如下。他们的规格表中的所有数据都是“desc”,而每个部分的标题都是“name”。下面是来自 Newegg 页面的两个数据示例。

<tr>
    <td class="name">Brand</td>
    <td class="desc">Intel</td>
</tr>
<tr>
    <td class="name">Series</td>
    <td class="desc">Core i5</td>
</tr>
<tr>
    <td class="name">Cores</td>
    <td class="desc">4</td>
</tr>
<tr>
    <td class="name">Socket</td>
    <td class="desc">LGA 1156</td>

<tr>
    <td class="name">Brand</td>
    <td class="desc">AMD</td>
</tr>
<tr>
    <td class="name">Series</td>
    <td class="desc">Phenom II X4</td>
</tr>
<tr>
    <td class="name">Cores</td>
    <td class="desc">4</td>
</tr>
<tr>
    <td class="name">Socket</td>
    <td class="desc">Socket AM3</td>
</tr>

最后,我希望有一个用于 CPU 的类(已经设置),它由 Brand、Series、Cores 和 Socket 类型组成,用于存储每个数据。这是我能想到的唯一方法:

if(parsedDocument.xpath(tr/td[@class="name"])=='Brand'):
    CPU.brand = parsedDocument.xpath(tr/td[@class="name"]/nextsibling?).text

并为其余的值执行此操作。我将如何完成下一个兄弟姐妹,有没有更简单的方法来做到这一点?


D
Dimitre Novatchev

我将如何完成下一个兄弟姐妹,有没有更简单的方法来做到这一点?

您可以使用:

tr/td[@class='name']/following-sibling::td

但我宁愿直接使用:

tr[td[@class='name'] ='Brand']/td[@class='desc']

这假设:

评估 XPath 表达式所依据的上下文节点是所有 tr 元素的父级 - 未在您的问题中显示。每个 tr 元素只有一个类属性值为“name”的 td 和一个类属性值为“desc”的 td。


请注意,您必须小心使用类。当您的“名称”类元素同时具有任何其他类时,td[@class='name'] 将中断。有关详细信息,请参阅 this question
@gm2008,是的,如果@class 属性的值中有多个类,则要使用的谓词是: contains(concat(' ', @class, ' '), ' name ') 。但在这个问题中,@class 属性确实只有单个值。
相对于元素:./following-sibling::td
@JohnGietzen,回复:“相对于元素”-您的意思是如果 context 节点 是我们感兴趣的元素。在这种情况下,您可以省略 ./ 。另外,如果要选择紧随其后的同级,请使用:following-sibling::td[1],否则,如果有多个以下同级,则将全部选中。
P
Philipp

试试 following-sibling 轴 (following-sibling::td)。


M
Milan

为了完整性-添加到上面接受的答案-如果您对任何兄弟感兴趣,而不管元素类型如何,您都可以使用变体:

following-sibling::*