You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术问询:使用XPath获取页面两集合交集及多组标签间文本

我来帮你解决这两个XPath问题,都是网页爬取里很常见的场景:

1. 用XPath获取两个集合的所有交集

这个需求的实现要看你用的是XPath 2.0及以上版本,还是只能用XPath 1.0(很多老工具或库还在依赖1.0):

  • XPath 2.0+ 写法(推荐,更简洁):
    直接用intersect运算符,它会返回两个节点集合的交集。比如你要找同时属于//div[@class='group1']和//div[@class='group2']的节点,写法是:
//div[@class='group1'] intersect //div[@class='group2']
  • XPath 1.0 写法(兼容旧环境):
    1.0没有intersect,可以用谓语筛选。如果两个集合的节点有共同属性,直接用多条件判断:
//div[@class='group1' and @class='group2']

如果是更通用的交集(比如两个集合没有共同属性,只是节点重叠),可以用集合计数的技巧:

//div[@class='group1'][count(. | //div[@class='group2']) = count(//div[@class='group2'])]

原理是:如果当前节点属于第二个集合,那么两个集合的并集大小等于第二个集合的大小。

2. 获取多组标签对之间的文本

你的现有代码是针对单组a[@name="dst100030"]和a[@name="dst100031"]之间的pre文本,要批量处理多组的话,分两种情况:

情况1:使用XPath 2.0+(支持循环和变量)

如果你的爬虫工具支持XPath 2.0(比如Saxon、lxml的某些配置),可以用for循环遍历所有起始的a标签,自动匹配对应的结束a标签,一次性获取所有组的文本:

假设页面里的a标签是按起始-结束-起始-结束的顺序排列的(比如dst100030→dst100031→dst100032→dst100033...),写法可以是:

for $start_a in //a[@name][position() mod 2 = 1] 
return //pre[
  preceding-sibling::a[@name = $start_a/@name] 
  and following-sibling::a[@name = $start_a/following-sibling::a[1]/@name]
]//text()

或者更简洁的写法(如果每组的pre正好在起始a和下一个a之间):

for $a in //a[@name] 
return if ($a/following-sibling::a) then $a/following-sibling::pre[1]//text() else ()

这个写法会遍历每个a标签,取它后面第一个pre的文本(如果后面还有下一个a的话),正好对应每组标签对之间的内容。

情况2:只能用XPath 1.0(无循环支持)

XPath 1.0不支持变量和循环,这种情况下确实需要先提取所有a标签的@name值列表,然后逐个替换到你的原有XPath中,循环处理每组。比如先获取所有name值:

//a/@name

得到列表后,遍历每一对连续的name(比如第1和第2个,第3和第4个...),替换成你原来的XPath模板:

//pre[preceding-sibling::a[@name="替换为起始name"] and following-sibling::a[@name="替换为结束name"]]//text()

内容的提问来源于stack exchange,提问作者JBJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:05:09