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

如何在XPath查询中排除元素?以BBC美食网站食材列表为例

解决BBC Good Food食材列表提取时排除Tooltip文本的问题

嘿,我来帮你搞定这个提取食材文本的麻烦事儿!你的核心问题是要从带tooltip的食材列表项里提取干净的食材内容,而之前的XPath没过滤掉tooltip里的文本,咱们一步步来修正:

为什么你的原XPath不生效?

你写的//li[@class='ingredients-list__item'][not(div[@class='gf-tooltip'])]//text()有两个关键问题:

  1. 筛选条件[not(div[@class='gf-tooltip'])]是在找不包含tooltip的li,但你要处理的目标li恰恰是包含这个tooltip的,所以这个条件直接把你需要的元素排除了;
  2. 就算选对了li,//text()会递归取出所有子节点的文本,包括tooltip里的内容,自然会拿到不需要的tooltip文本。

正确的XPath写法

方法1:过滤掉tooltip祖先的文本节点

这个XPath会选中li下所有文本节点,但自动排除那些属于tooltip的文本:

//li[@class='ingredients-list__item']//text()[not(ancestor::div[@class='gf-tooltip'])]

用Scrapy提取后,只需要把文本片段拼接并清理一下:

# 提取文本片段
text_fragments = s.xpath("//li[@class='ingredients-list__item']//text()[not(ancestor::div[@class='gf-tooltip'])]").extract()
# 拼接并去除多余空格
clean_ingredient = ''.join(text_fragments).strip()
# 结果就是你要的:'400g new potato, halved if large'

方法2:精准选取目标文本节点

如果你想更精准地选取li的直接文本(比如重量、备注)和a标签里的食材名称(排除tooltip),可以用这个组合XPath:

//li[@class='ingredients-list__item']/text() | //li[@class='ingredients-list__item']/a//text()[not(ancestor::div[@class='gf-tooltip'])]

这个写法是把li的直接文本和a标签里非tooltip的文本组合起来,最终结果和方法1完全一致。

测试小技巧

你可以在浏览器开发者工具的Console里用$x("你的XPath表达式")来快速验证结果,比如输入上面的XPath,就能看到返回的文本片段都是你需要的内容,没有tooltip里的文字~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:32:05