XPath的@符号是什么意思?怎么选择属性?

畫卷琴夢
发布: 2025-08-11 21:24:02
原创
888人浏览过
<p>xpath中根据属性值定位元素的关键是使用@符号结合属性名和匹配条件,最常见的写法是//tagname[@attributename='attributevalue'],例如//div[@id='main']可精准定位id为main的div元素;当需要处理不完全匹配的场景时,可借助contains(@attributename, 'substring')判断属性值是否包含指定子串,如//[contains(@class, 'active')]用于匹配class包含active的元素;starts-with(@attributename, 'prefix')可匹配以特定字符串开头的属性值,如//[starts-with(@id, 'user-')]用于选取id以user-开头的元素;ends-with函数(仅xpath 2.0+支持)可判断结尾字符串;normalize-space()可用于清理属性值中的多余空白;还可通过and、or逻辑运算符组合多个属性条件,如//a[@href='/products' and @class='nav-link'];当属性名不确定时,可用@匹配任意属性,或结合name()函数判断属性名,如//[starts-with(name(@*), 'data-')]用于选取具有以data-开头属性名的元素;此外,属性选择(@)与文本内容选择(text())有本质区别,@用于获取标签内的元数据(如id、class),而text()用于获取标签间的文本内容,二者不可混淆,正确理解这一差异是高效使用xpath的基础。

<p>XPath的@符号是什么意思?怎么选择属性?

<p>XPath表达式中的
@
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
符号,它是一个明确的指示符,告诉解析器你正在寻找的是元素的“属性”(attribute),而不是它的子元素或文本内容。简单来说,它就是用来选择HTML或XML标签内部那些键值对信息(比如
id="myId"
登录后复制
class="button"
登录后复制
)的。当你需要根据这些属性来定位或提取数据时,
@
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
符号就是你的利器。

解决方案

<p>理解
@
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
符号的关键在于,它将你的焦点从元素本身转移到了元素的元数据上。一个HTML标签,比如
<div id="main" class="container">
登录后复制
,它有
div
登录后复制
登录后复制
登录后复制
登录后复制
这个标签名,也有
id
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
class
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
这两个属性。如果你想选择这个
div
登录后复制
登录后复制
登录后复制
登录后复制
元素,通常会用
//div
登录后复制
。但如果你想基于它的
id
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
属性来选择,或者仅仅是想获取它的
class
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
属性值,
@
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
就派上用场了。

<p>最常见的用法是
@attributeName
登录后复制
登录后复制
。例如,要选择所有带有
id
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
属性的元素,你可以写
//*[@id]
登录后复制
。这里的
*
登录后复制
登录后复制
代表任何元素,
[@id]
登录后复制
则表示这个元素必须有一个
id
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
属性。如果我想更精确地选择那个
id
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
main
登录后复制
div
登录后复制
登录后复制
登录后复制
登录后复制
,表达式会是
//div[@id='main']
登录后复制
。这真的是我用XPath时最常用的模式之一,因为它能非常精准地定位到页面上独一无二的元素。

<p>当然,你也可以直接选择某个元素的特定属性值。比如,要获取上述
div
登录后复制
登录后复制
登录后复制
登录后复制
class
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
属性值,表达式是
//div[@id='main']/@class
登录后复制
。这个表达式会返回
container
登录后复制
这个字符串。这种能力在处理那些内容不固定,但属性值相对稳定的元素时特别有用,比如一个按钮的
data-action
登录后复制
属性。

<p>XPath其实也提供了一个更冗长的写法,叫做
attribute::attributeName
登录后复制
,比如
//div/attribute::id
登录后复制
。但说实话,日常开发中几乎没人这么写,
@
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
符号实在是太简洁、太直观了,它已经成了XPath里一个约定俗成的惯例。在我看来,这种简洁性是XPath能够如此流行的原因之一。

XPath中如何根据属性值定位元素?

<p>在我个人的经验里,根据属性值定位元素是XPath最核心、最实用的功能之一,简直是网页抓取和自动化测试的基石。当你面对一个复杂的网页,仅仅靠标签名或层级关系往往不够,因为很多元素可能长得一样,但它们的属性值却能区分彼此。

<p>最直接的方式就是使用等号
=
登录后复制
进行精确匹配:
//tagName[@attributeName='attributeValue']
登录后复制
例如,如果你想找到所有
class
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
属性值为
button primary
登录后复制
的按钮,你可以写:
//button[@class='button primary']
登录后复制
这会找到所有
<button class="button primary">...</button>
登录后复制
这样的元素。

<p>但实际情况往往更复杂,属性值可能不完全匹配,或者包含动态部分。这时候,XPath提供了一些非常实用的函数来处理这种情况:

  • <p>
    contains(string, substring)
    登录后复制
    :检查一个字符串是否包含另一个子字符串。这在我处理CSS类名时特别常见,一个元素可能同时有多个类,比如
    class="item active selected"
    登录后复制
    。如果我只关心它是否是
    active
    登录后复制
    登录后复制
    的,我就会用:
    //*[contains(@class, 'active')]
    登录后复制
    这会匹配任何
    class
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    属性中包含
    active
    登录后复制
    登录后复制
    这个词的元素。这比精确匹配要灵活得多,也更能适应前端框架动态添加类名的场景。

  • <p>
    starts-with(string, substring)
    登录后复制
    :检查一个字符串是否以某个子字符串开头。这对于那些有命名规范的属性非常有用,比如
    id="user-123"
    登录后复制
    id="user-456"
    登录后复制
    。如果你想找到所有用户相关的元素,可以这样:
    //*[starts-with(@id, 'user-')]
    登录后复制

  • <p>
    ends-with(string, substring)
    登录后复制
    (XPath 2.0及以上支持,很多浏览器内置的XPath解析器可能不支持,需要注意兼容性):检查一个字符串是否以某个子字符串结尾。
    //*[ends-with(@src, '.png')]
    登录后复制

  • <p>
    normalize-space(string)
    登录后复制
    :移除字符串开头和结尾的空白字符,并用单个空格替换字符串内部的连续空白字符。这在处理一些不规范的HTML时非常有用,比如属性值可能有多余的空格。
    //div[normalize-space(@class)='card']
    登录后复制

  • <p>
    or
    登录后复制
    登录后复制
    and
    登录后复制
    运算符
    :你可以组合多个条件来更精确地定位。
    //a[@href='/products' and @class='nav-link']
    登录后复制
    或者
    //button[@id='submit' or @name='send']
    登录后复制

<p>这些灵活的匹配方式,让XPath在处理各种复杂的网页结构时显得游刃有余。我经常发现,一个看似无从下手的问题,通过巧妙地组合这些属性匹配函数,就能迎刃而解。

当属性名不确定时,XPath如何灵活选择?

<p>有时候,你会遇到一些“顽皮”的网页,它们的属性名可能不是固定的,或者你希望选择所有具有任何属性的元素。这种情况下,XPath同样提供了解决方案,让我觉得它在设计上考虑得相当周全。

<p>最直接的方式是使用
*
登录后复制
登录后复制
通配符来匹配任何属性:
//*[@*]
登录后复制
这个表达式会选择页面上所有至少拥有一个属性的元素。这在某些场景下非常有用,比如你想统计页面上所有带有自定义属性(如
data-*
登录后复制
)的元素,但你不知道具体的属性名。

<p>如果你需要更进一步,例如,你只想选择那些属性名以特定前缀开头的属性,或者你想获取所有属性的名称,
name()
登录后复制
函数就能派上用场了。
//*[starts-with(name(@*), 'data-')]
登录后复制
这个表达式会选择所有至少有一个属性,且该属性名以
data-
登录后复制
登录后复制
登录后复制
开头的元素。这对于处理现代前端框架中大量使用的
data-
登录后复制
登录后复制
登录后复制
属性非常有效。比如,你可能想抓取所有
data-id
登录后复制
data-value
登录后复制
的元素,而不需要关心具体的
data-
登录后复制
登录后复制
登录后复制
属性名是什么。

<p>另一个场景是,你可能知道元素肯定有一个特定的属性,但它的名字可能会变。例如,一个验证码图片的URL可能在
src
登录后复制
登录后复制
属性里,也可能在
data-src
登录后复制
登录后复制
里。这时候,你可以用
or
登录后复制
登录后复制
来尝试匹配多个可能的属性名:
//img[@src or @data-src]
登录后复制
这会匹配任何有
src
登录后复制
登录后复制
属性或者有
data-src
登录后复制
登录后复制
属性的
img
登录后复制
标签。

<p>虽然这些高级用法不那么常用,但它们的存在,无疑增强了XPath处理复杂、动态网页的能力。我个人觉得,当你需要处理一些“非典型”的定位需求时,这些技巧往往能帮你打开思路。

XPath属性选择与文本内容选择有何不同?

<p>这是XPath初学者经常会混淆的一个点,但理解它们的区别至关重要。简单来说,属性选择是关于元素“标签内部的元信息”,而文本内容选择则是关于元素“标签之间包裹的内容”。

<p>想象一个HTML片段:
<p class="intro">Hello <span>World</span>!</p>
登录后复制

  1. <p>属性选择 (
    @
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    )
    : 当你使用
    @
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    符号时,你是在关注
    <p>
    登录后复制
    登录后复制
    标签内部的
    class="intro"
    登录后复制
    这部分。

    • //p/@class
      登录后复制
      :这会返回
      intro
      登录后复制
      。它获取的是
      p
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      元素的
      class
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      属性的值。
    • 你不能用
      //p/@text()
      登录后复制
      ,因为
      text()
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      不是一个属性,它是内容。
  2. <p>文本内容选择 (
    text()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    )
    : 当你使用
    text()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    函数时,你是在关注
    <p>
    登录后复制
    登录后复制
    标签开始和结束标签之间包裹的可见文本。

    • //p/text()
      登录后复制
      :这会返回
      Hello
      登录后复制
      !
      登录后复制
      (注意,它会返回直接子文本节点,不包含子元素
      <span>
      登录后复制
      内的文本)。
    • 如果你想获取一个元素及其所有子元素拼接起来的完整文本内容(包括
      <span>World
      登录后复制
      中的
      World
      登录后复制
      ),通常会直接选择元素,然后获取其
      string-value
      登录后复制
      ,或者在某些库中调用
      .text()
      登录后复制
      方法。在XPath表达式中,
      //p
      登录后复制
      通常会代表整个
      p
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      元素的节点,当它被转换为字符串时,会包含其所有后代文本。
    • 你不能用
      //p[@text()='Hello World!']
      登录后复制
      来定位,因为
      text()
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      登录后复制
      是节点测试,不是属性。正确的定位方式是
      //p[contains(., 'Hello World!')]
      登录后复制
      或者
      //p[text()='Hello World!']
      登录后复制
      (如果文本是直接子节点)。
<p>核心区别总结:

  • @attributeName
    登录后复制
    登录后复制
    :指向元素的某个特定属性的值。它存在于元素的“开标签”内部。
  • text()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    :指向元素的直接文本子节点。它存在于元素的“开标签”和“闭标签”之间。
  • .
    登录后复制
    登录后复制
    (点号)
    :在谓语中,
    .
    登录后复制
    登录后复制
    代表当前节点。当用于字符串比较时,它通常会取当前节点的字符串值,这通常是其所有后代文本内容的拼接。例如,
    //p[contains(., 'World')]
    登录后复制
    会匹配包含“World”的
    p
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    元素,无论“World”是在
    p
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    的直接文本中还是在其子元素
    span
    登录后复制
    中。
<p>理解这个根本差异,是高效编写XPath表达式的关键。在我看来,区分清楚“元数据”(属性)和“实际内容”(文本)是XPath学习过程中非常重要的一步,它能帮助你避免很多常见的错误,并更精准地定位目标。

以上就是XPath的@符号是什么意思?怎么选择属性?的详细内容,更多请关注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号