
本文介绍如何通过XPath的“或”逻辑(|)将两个不同结构的CSS类选择器合并为单一表达式,从而统一提取网页中分散在不同HTML结构中的运费文本内容。
本文介绍如何通过xpath的“或”逻辑(`|`)将两个不同结构的css类选择器合并为单一表达式,从而统一提取网页中分散在不同html结构中的运费文本内容。
在实际网页数据抓取场景中,同一类信息(如“运费”)常因前端模板差异而存在于结构迥异的HTML节点中。例如,某电商页面的运费可能出现在两种典型结构中:
- 类名为 flex flex-row justify-between f6 mid-gray pt2 的容器内,目标文本位于其子 div[2] 或带 green 类的 div 中;
- 类名为 mid-gray flex items-center 的容器内,目标文本包裹在 span 标签中。
若分别维护两套XPath并手动切换,不仅代码冗余,也易出错。更优雅的方式是使用XPath 1.0的联合选择器(Union Operator) |,将多个路径表达式合并为一个可返回首个匹配结果的查询。
✅ 推荐合并XPath如下:
(//*[@class="flex flex-row justify-between f6 mid-gray pt2"]/div[@class="green"] | //*[@class="mid-gray flex items-center"]/span)[1]/text()
? 关键解析:
立即学习“前端免费学习笔记(深入)”;
- (... | ...):括号确保两个路径作为整体参与运算,| 表示逻辑“或”,返回所有匹配节点的并集;
- [1]:取并集中第一个匹配到的节点(而非每个路径的第一个),确保结果唯一且优先命中最先出现的有效结构;
- /text():精准提取文本内容,避免包裹标签或空白字符干扰;
- 注意:@class 匹配要求完全一致(XPath不支持类名子串匹配),若实际HTML中存在额外空格或动态类名,建议改用 contains(@class, "mid-gray") and contains(@class, "flex") 提升鲁棒性。
⚠️ 注意事项:
- 此写法依赖XPath 1.0及以上(主流解析库如 lxml、Scrapy、Selenium 均支持);
- 若两个路径均无匹配,结果为空列表,需在代码中做空值判断(如 Python 中检查 result or None);
- 避免滥用 // 开头的全局搜索——在已知父级上下文时,优先使用相对路径提升性能与稳定性。
? 进阶建议:
对于长期维护的爬虫项目,推荐封装为可复用函数,并结合 cssselect 或 lxml.etree.XPath 预编译表达式以提高效率:
from lxml import html
def extract_shipping_fee(tree):
xpath = '''(//*[@class="flex flex-row justify-between f6 mid-gray pt2"]/div[@class="green"]
| //*[@class="mid-gray flex items-center"]/span)[1]/text()'''
result = tree.xpath(xpath)
return result[0].strip() if result else None
# 使用示例
# doc = html.fromstring(html_content)
# fee = extract_shipping_fee(doc)通过合理组合XPath逻辑运算符,既能兼顾多变的HTML结构,又能保持提取逻辑简洁、健壮、可维护。



















