XPath的contains()方法怎么用?有哪些应用场景?

畫卷琴夢
发布: 2025-08-15 17:26:01
原创
275人浏览过
“淘宝第一个程序员”蔡景现(花名多隆)已从阿里巴巴离职,结束25年任职生涯。作为淘宝初创核心工程师,他构建了淘宝交易系统,以技术实力闻名,曾以26亿身家登上胡润富豪榜,其阿里内外状态已显示为“退隐江湖”。

xpath的contains()方法怎么用?有哪些应用场景?

XPath的

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
方法,简单来说,就是用来判断一个字符串是否包含另一个特定的子字符串。它在处理那些内容不完全固定、但部分特征可识别的网页元素时,简直是神器。比如,你想找一个按钮,它的类名总是变,但里面肯定包含“submit”这个词,或者一个文本段落,它总是有“订单号”这几个字,但后面的数字每次都不同,这时候
contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
就能派上大用场。

解决方案

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
方法的语法非常直观:
contains(string, substring)
登录后复制
登录后复制
。第一个参数是你想要检查的字符串(比如元素的文本内容或某个属性的值),第二个参数是你想要查找的子字符串。

举几个实际例子:

  • 查找文本中包含特定内容的元素: 假设你想找到所有包含“最新消息”这几个字的

    div
    登录后复制
    登录后复制
    登录后复制
    元素。
    //div[contains(text(), '最新消息')]
    登录后复制
    这里,
    text()
    登录后复制
    函数获取元素的文本内容,然后
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    判断其是否包含“最新消息”。

  • 查找属性值中包含特定内容的元素: 如果有一个链接,它的

    href
    登录后复制
    登录后复制
    属性值总是包含“product”这个词,但后面可能跟着不同的ID。
    //a[contains(@href, 'product')]
    登录后复制
    @href
    登录后复制
    表示获取
    href
    登录后复制
    登录后复制
    属性的值。

  • 处理动态类名: 很多前端框架会生成动态的CSS类名,比如

    btn-primary-dsf23k
    登录后复制
    ,但核心部分
    btn-primary
    登录后复制
    登录后复制
    是不变的。
    //button[contains(@class, 'btn-primary')]
    登录后复制
    登录后复制
    这比用
    @class='btn-primary-dsf23k'
    登录后复制
    这种完全匹配要灵活得多。

  • 结合其他条件使用: 你也可以将

    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    与其他XPath表达式结合起来,进行更精确的定位。
    //div[contains(@id, 'item') and contains(text(), '详情')]
    登录后复制
    这会找到所有
    id
    登录后复制
    登录后复制
    包含“item”且文本内容包含“详情”的
    div
    登录后复制
    登录后复制
    登录后复制
    元素。

XPath
contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
starts-with()
登录后复制
登录后复制
登录后复制
登录后复制
ends-with()
登录后复制
登录后复制
登录后复制
有什么区别

说实话,XPath这东西,用好了就是利器,但刚上手时,

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
starts-with()
登录后复制
登录后复制
登录后复制
登录后复制
ends-with()
登录后复制
登录后复制
登录后复制
这几个哥们儿确实容易让人混淆。它们都是字符串匹配,但侧重点完全不一样。

  • starts-with(string, substring)
    登录后复制
    :顾名思义,它只检查一个字符串是否指定的子字符串开头。 比如,你有一堆ID是
    user_1
    登录后复制
    user_2
    登录后复制
    admin_1
    登录后复制
    的元素,你想找所有用户相关的元素,用
    starts-with(@id, 'user')
    登录后复制
    就非常精准。它不会匹配到
    super_user_1
    登录后复制
    这种ID。

  • ends-with(string, substring)
    登录后复制
    :这个方法在XPath 2.0及更高版本中才支持,它检查一个字符串是否指定的子字符串结尾。 如果你想找所有以
    .png
    登录后复制
    结尾的图片链接,
    //img[ends-with(@src, '.png')]
    登录后复制
    就很方便。在一些老旧的系统或者XPath 1.0的环境里,你可能得想别的办法,比如用
    substring()
    登录后复制
    string-length()
    登录后复制
    组合来模拟。

  • contains(string, substring)
    登录后复制
    登录后复制
    :而
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    就宽松多了,它不关心子字符串在原字符串的开头、结尾还是中间,只要有,它就认为匹配。 这就像是“模糊匹配”的王者。比如,一个元素的类名可能是
    active-item
    登录后复制
    ,也可能是
    item-active
    登录后复制
    ,或者
    main-item-active-status
    登录后复制
    ,只要里面有
    item
    登录后复制
    ,你用
    contains(@class, 'item')
    登录后复制
    都能抓到。

什么时候用哪个?

  • 当你明确知道目标字符串的前缀时,用
    starts-with()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
  • 当你明确知道目标字符串的后缀时(且环境支持),用
    ends-with()
    登录后复制
    登录后复制
    登录后复制
  • 当目标子字符串可能出现在任何位置,或者你只想进行一个宽泛的包含匹配时,
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    是你的首选。

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
方法在处理动态类名或文本时有哪些实战技巧?

很多时候,我们抓取网页或者自动化测试时,会遇到一些让人头疼的动态元素。它们的ID、类名或者文本内容,可能每次加载都变一部分。这时候,

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
的灵活就体现出来了。

  1. 动态类名处理的“万金油”: 设想一下,一个按钮,今天它的类名是

    btn-primary-randomhash123
    登录后复制
    ,明天可能变成
    btn-primary-anotherhash456
    登录后复制
    。你不可能每次都去 inspect 元素拿到完整的类名。但核心的
    btn-primary
    登录后复制
    登录后复制
    通常是固定的。
    //button[contains(@class, 'btn-primary')]
    登录后复制
    登录后复制
    这招屡试不爽,能大幅提升你的XPath表达式的健壮性。甚至有些元素可能有多个类名,比如
    <div class="item active selected">
    登录后复制
    ,如果你只想找到所有“活跃”的项,而不管它是不是“选中”的,
    //div[contains(@class, 'active')]
    登录后复制
    就能精准命中。

  2. 处理部分变化的文本内容: 网页上经常有这种文本:“您的订单号是:ABC123456789”,或者“当前库存:150件”。其中“ABC123456789”和“150”是动态变化的。

    //p[contains(text(), '您的订单号是:')]
    登录后复制
    //span[contains(text(), '当前库存:') and contains(text(), '件')]
    登录后复制
    (这里用两个
    contains
    登录后复制
    来确保匹配的精确性,避免只匹配到“当前库存”或“件”的意外情况) 这样,即使订单号或库存量变了,你的XPath依然能准确找到目标元素。

  3. 应对大小写不敏感的需求(XPath 1.0 局限):

    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    是大小写敏感的。这意味着
    contains(text(), 'hello')
    登录后复制
    不会匹配到“Hello”。在XPath 1.0中,要实现大小写不敏感,你需要借助
    translate()
    登录后复制
    登录后复制
    函数,将字符串中的大写字母转换为小写,然后再进行
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    判断。
    //div[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'hello')]
    登录后复制
    这看起来有点长,但确实是XPath 1.0里比较通用的做法。如果你的环境支持XPath 2.0,那就可以用
    lower-case()
    登录后复制
    登录后复制
    函数,会简洁很多:
    //div[contains(lower-case(text()), 'hello')]
    登录后复制
    。了解这些,能让你在遇到实际问题时,知道如何变通。

使用
contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
时可能遇到哪些常见问题和性能考量?

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
虽然好用,但用起来也有些小坑和需要注意的地方。

  1. 大小写敏感性陷阱: 这是最常见的“坑”之一。很多人以为

    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    会智能地忽略大小写,结果发现怎么也匹配不上。比如
    contains(@class, 'active')
    登录后复制
    不会匹配到
    Active
    登录后复制
    。遇到这种情况,要么老老实实写精确的大小写,要么就得用上面提到的
    translate()
    登录后复制
    登录后复制
    或者
    lower-case()
    登录后复制
    登录后复制
    来处理。

  2. 过度匹配的风险:

    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    的“模糊”特性,有时也会带来过度匹配的问题。如果你想找一个
    class
    登录后复制
    item-list
    登录后复制
    的元素,却写了
    //div[contains(@class, 'item')]
    登录后复制
    ,那么可能
    item-detail
    登录后复制
    sub-item
    登录后复制
    等所有包含“item”的元素都会被匹配到,这显然不是你想要的。 解决办法是:尽可能结合其他更精确的定位方式来缩小范围,比如先用ID或更具体的父级路径,再使用
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    。 例如,
    //div[@id='main-content']//li[contains(@class, 'product-item')]
    登录后复制
    就比
    //li[contains(@class, 'product-item')]
    登录后复制
    更精准,因为它限定了只在
    id
    登录后复制
    登录后复制
    main-content
    登录后复制
    div
    登录后复制
    登录后复制
    登录后复制
    内部查找。

  3. 性能考量(虽然通常不是大问题): 对于现代浏览器和XPath引擎来说,

    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    的性能通常不是瓶颈,但在极端情况下,比如处理非常庞大、复杂的XML文档,或者在循环中大量使用
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    ,还是值得注意一下。 相比于直接的属性匹配(如
    @id='someId'
    登录后复制
    )或
    starts-with()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    contains()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    需要遍历整个字符串来查找子串,理论上会稍微慢一点点。不过,这种差异在大多数网页抓取或自动化场景中几乎可以忽略不计。 真正的性能杀手往往是那些过于宽泛的XPath,比如
    //*[contains(text(), '某个词')]
    登录后复制
    。这种表达式会扫描整个文档树,效率会比较低。所以,尽量从一个更具体的父节点开始,缩小搜索范围,总是一个好习惯。

总的来说,

contains()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
是一个非常实用的工具,掌握它的用法和特性,能让你在处理动态网页内容时更加游刃有余。

以上就是XPath的contains()方法怎么用?有哪些应用场景?的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号