XPath的following-sibling轴如何选择同级?

following-sibling轴用于选择当前节点之后同父级的所有同级节点,其定位精准且仅限于兄弟节点范围内,不会涉及父级、子级或其他无关部分;与following轴不同,following-sibling仅在同级节点中向后查找,而following轴则全局查找文档中所有后续节点,范围更广;通过结合节点名称、位置、属性、文本内容及谓词条件,可实现对特定后续同级节点的精确筛选;在实际网页抓取中,虽面临结构不稳定、动态加载、同级节点混淆、性能开销及不规范html等挑战,但可通过稳定锚点、等待机制、上下文分析和组合定位等策略有效应对,从而构建可靠高效的xpath定位方案。

XPath的

following-sibling

轴用于选择当前节点之后,与当前节点共享同一父节点的所有同级节点。它是一个非常实用的定位工具,能够帮助我们精准地找到特定元素后面的兄弟姐妹们,而不会牵扯到父级、子级或文档中其他不相关的部分。

解决方案

following-sibling

轴是XPath中一个非常直接且专一的定位方式。想象一下,你站在一排并肩站立的人群中,

following-sibling

就像是你的目光只向右看,找到你身后的所有兄弟姐妹。它从当前节点的“右侧”开始,沿着文档顺序查找所有与当前节点拥有相同父节点的元素。

其基本语法是:

当前节点/following-sibling::节点测试


这里的“节点测试”可以是具体的元素名(如

div

p

),也可以是通配符

*

(表示任何元素)。

举个例子,如果你有一个HTML结构:

第一个段落

一个跨度

第二个段落

一个区块

第三个段落

如果你当前定位在

一个跨度

这个节点上,使用

./following-sibling::*

,你将选中

第二个段落

一个区块

第三个段落

这个轴的强大之处在于它的“同级”限定。它不会跳到父节点的其他子节点,也不会深入到任何兄弟节点的内部去寻找后代。这种精确性在处理列表、表格或者任何有明确顺序的同级元素时显得尤为重要。

following-sibling

following

轴有何不同?

这确实是一个常让人混淆的点,因为名字听起来很像,但它们的功能范围却大相径庭。简单来说,

following-sibling

是“同级限定”的,而

following

轴则是“全局向后”的。

following-sibling

轴,就像我们刚才说的,它只关心与当前节点有同一个父节点,并且在文档顺序上位于当前节点之后的所有兄弟节点。它不会越过父级的边界,也不会钻进兄弟节点的内部去寻找后代。它非常“守规矩”,只在自己的“兄弟圈子”里找。

following

轴就“奔放”多了。它会选择文档中所有在当前节点之后出现的节点,无论这些节点是不是当前节点的兄弟,是不是它的后代,甚至是不是在同一个父级下。它会遍历文档中所有位于当前节点之后的位置,包括其他分支的节点,甚至其他主要部分的节点。

举个例子,假设有这样的HTML片段:

P1

S1

P2

P3

S2

如果你当前定位在

S1

这个节点:

  • 使用
    ./following-sibling::*

    ,你只会选中

    P2

    。因为它是

    S1

    的同级兄弟,且位于

    S1

    之后。

  • 使用
    ./following::*

    ,你将选中

    P2

    P3

    S2

    。因为它会查找文档中所有在

    S1

    之后出现的节点,包括其同级、同级元素的后代(如果存在)、以及文档中后续的任何元素。

所以,当你明确知道目标元素就在当前元素的旁边,且是同级时,

following-sibling

是首选,它更精确,也通常更高效。当你需要查找文档中任何位于当前元素之后,但关系不那么明确的元素时,

following

轴才派上用场。

如何精确选择特定类型的后续同级节点?

仅仅使用

following-sibling::*

可能过于宽泛,很多时候我们需要更精细的控制。XPath的强大之处在于它允许你通过谓词(

[]

)来进一步筛选结果。

  1. 按节点名称筛选:
    这是最常见的用法。如果你知道你想要的后续同级节点是什么类型的元素,直接指定它的标签名。
    例如:

    ./following-sibling::p

    会选择所有后续的

    同级节点。

    ./following-sibling::div

    会选择所有后续的

    同级节点。

  2. 按位置筛选:
    当你需要选择第N个后续同级节点时,可以使用

    [position()]


    例如:

    ./following-sibling::p[1]

    会选择当前节点之后的第一个

    同级节点。

    ./following-sibling::*[last()]

    会选择所有后续同级节点中的最后一个。

    ./following-sibling::*[position() > 1 and position() < 4]

    会选择第二个到第三个后续同级节点。

  3. 按属性筛选:
    如果后续同级节点有特定的属性,你可以用

    [@attribute='value']

    来定位。
    例如:

    ./following-sibling::div[@class='info']

    会选择所有后续的

    同级节点中,

    class

    属性值为

    info

    的节点。

    ./following-sibling::p[contains(@id, 'summary')]

    会选择所有后续的

    同级节点中,

    id

    属性包含

    summary

    的节点。

  4. 按文本内容筛选:
    你也可以根据同级节点的文本内容进行筛选,这在某些场景下非常有用。
    例如:

    ./following-sibling::span[contains(text(), '重要信息')]

    会选择所有后续的

    同级节点中,包含“重要信息”文本的节点。

    ./following-sibling::h2[normalize-space(.) = '产品详情']

    会选择后续的

    同级节点中,文本内容(去除首尾空白)精确为“产品详情”的节点。

  5. 组合筛选条件:
    这些条件可以组合使用,以实现更复杂的定位。
    例如:

    ./following-sibling::p[@class='item' and position() = 2]

    会选择所有后续的

    同级节点中,

    class

    item

    且是第二个出现的节点。

通过这些谓词的灵活运用,

following-sibling

轴的定位能力得到了极大的增强,能够帮助我们从复杂的HTML结构中精确地提取所需信息。

following-sibling

轴在实际网页抓取中可能遇到哪些挑战?

尽管

following-sibling

轴非常强大且精准,但在实际的网页抓取或自动化过程中,它也并非万无一失,会遇到一些挑战。理解这些挑战有助于我们构建更健壮、更适应变化的抓取策略。

  1. 网页结构的不稳定性: 这是最常见的挑战。很多网站,特别是那些频繁更新或由内容管理系统驱动的网站,其HTML结构可能会在不经意间发生变化。一个原本位于特定元素之后的兄弟节点,可能因为新元素的插入、旧元素的移除,或者只是顺序的调整,导致你依赖的

    following-sibling

    路径失效。

    • 应对思路: 尽量寻找更稳定的定位点(如带有唯一ID或稳定class的父节点),然后从该稳定点出发,结合

      following-sibling

      以及其他轴(如

      ./*

      ./div[2]

      )进行相对定位。或者,考虑使用多个备用XPath路径。

  2. 动态加载内容: 现代网页大量使用JavaScript进行内容渲染和异步加载。你期望通过

    following-sibling

    定位的元素,可能在初始页面加载时并不存在于DOM中,而是通过AJAX请求或用户交互后才动态添加。此时,如果你的抓取器在内容完全加载之前就尝试查找,就会失败。

    • 应对思路: 使用Selenium、Playwright等工具,它们能模拟浏览器行为,并提供等待机制(如

      WebDriverWait

      ),等待特定元素出现或特定条件满足后再执行XPath查询。

  3. 混淆的同级节点: 有时,一个元素后面可能会跟着很多同类型但语义不同的同级节点,或者这些节点之间没有明显的属性或文本差异来区分。例如,一系列没有独特class或id的

    • 应对思路: 这时候就需要结合上下文,可能需要回溯到它们的共同父节点,然后通过更复杂的谓词(如

      [contains(., '关键字')]

      [not(@class)]

      )来区分。或者,如果可能,尝试寻找一个更独特的“锚点”元素,从它开始定位。

  4. 性能考虑: 在非常庞大和复杂的HTML文档中,如果

    following-sibling

    轴的起始点位于文档较靠前的位置,并且后面跟着大量的同级节点,那么解析和遍历这些节点可能会带来一定的性能开销。虽然通常情况下这不是主要瓶颈,但在大规模抓取时也值得注意。

    • 应对思路: 尽量缩小搜索范围,从更具体的父节点或祖先节点开始,减少不必要的遍历。例如,如果目标元素在一个特定的

      div

      内部,先定位到那个

      div

      ,再在该

      div

      的上下文中进行

      following-sibling

      查找。

  5. 不规范的HTML结构: 某些网站的HTML可能不完全符合标准,或者存在一些结构上的“怪癖”。例如,本应是兄弟关系的元素,由于开发者疏忽,可能被错误地嵌套在另一个不相关的元素内部,导致

    following-sibling

    无法找到它们。

    • 应对思路: 这时候可能需要更灵活的策略,比如使用

      following::

      轴(如果目标在文档后面任何位置都行),或者回退到CSS选择器,甚至结合正则表达式来处理一些非常规的文本内容匹配。

总的来说,

following-sibling

是一个极其有用的工具,但它并非万能。在实际应用中,我们需要结合对网页结构的理解、对动态内容的感知,以及与其他XPath轴或定位方法的灵活组合,才能构建出稳定且高效的网页数据抓取解决方案。

以上就是XPath的following-sibling轴如何选择同级?的详细内容,更多请关注骃骐网【www.myinqi.com】。

相关推荐:

Python中SVM支持向量机如何选择核函数_对比Linear与RBF性能

应优先用LinearSVC而非SVC(kernel='linear')处理高维稀疏数据,因其更快、更稳、可解释;RBF核仅在低维/中维且边界明显非线性时才值得调参,且必须标准化后手动设gamma。 线性核(kernel='linear')在高维稀疏数据或样本量远大于特征数时,往往比RBF更快、更稳、更可解释;RBF核(kernel='rbf')只在低维/中维且边界明显非线性时才值得投入调参成本——...

Python类中的__str__和__repr__如何选择_实现易读的对象调试信息输出

该用 __str__ 时用于面向用户的易读字符串表示(如 print(obj)),必须写 __repr__ 时用于开发者调试,需包含关键字段且格式稳定;优先实现 __repr__,它缺失时无 fallback,而 __str__ 缺失会自动调用 __repr__。 什么时候该用 __str__,什么时候必须写 __repr__ __str__ 是给人看的,__repr__ 是给开发者/解释器看的。...

为什么需要在线运行PHP代码?如何选择合适的在线运行平台?

在线运行PHP代码的最大好处是省去本地环境搭建,适合快速测试、学习、分享和协作。它提供即时反馈,降低学习门槛,方便远程调试与教学,但无法完全替代本地开发环境。选择平台时需关注PHP版本、扩展支持、多文件处理、数据库集成、性能及安全性。在线工具是本地开发的有力补充,适用于轻量级任务,提升效率与协作体验。 在线运行PHP代码,在我看来,最直接的好处就是省去了本地环境搭建的繁琐与耗时。无论是为了快速测试...

什么是PHP在线IDE?如何选择适合自己的在线开发环境?

PHP在线IDE核心优势是即开即用、环境标准化与跨设备协作,省去本地配置麻烦,适合快速开发与团队协同;局限在于依赖网络、资源受限及底层控制力弱。选择时应关注代码编辑、调试、终端、Git集成与环境自定义能力,根据项目规模与团队需求权衡免费或企业级方案。 PHP在线IDE,简单来说,就是让你能直接在浏览器里写PHP代码、运行项目,甚至进行调试的开发环境。它把传统上需要在本地电脑上安装配置的各种工具——...

如何选择适合自己的耳塞套尺寸?

合适的耳塞套应舒适、密封且稳固。通过佩戴舒适度、低音表现和运动时的稳定性判断尺寸是否合适,左右耳可能需不同尺寸。硅胶套耐用易清洁,适合运动;海绵套舒适隔音好但寿命短,需定期更换。一般硅胶套每3-6个月更换,海绵套每1-3个月更换,出现破损或异味应立即更换。 选择合适的耳塞套尺寸,关键在于舒适度和密封性。太小会漏音,太大则会胀痛。尝试不同尺寸,找到那个既能稳固佩戴,又能让你几乎忘记它存在的那个。 选...

Golang开发IDE如何选择 对比VSCode与Goland配置技巧

VSCode轻量灵活,适合多语言和自定义配置;Goland功能深度集成,提升大型项目开发效率。选择取决于项目规模、团队协作、个人偏好与成本考量。 在Go语言的开发环境中,IDE的选择常常是开发者津津乐道的话题。究竟是追求轻量与极致自定义的VSCode,还是倾向于开箱即用、深度集成的Goland?这没有一个标准答案,更多的是一种个人偏好与项目需求的权衡。简单来说,VSCode以其灵活的插件生态和资源...

无线耳机编码格式如何选择以获得最佳音质?

选择支持LDAC或aptX Adaptive等高码率编码格式可提升音质,需结合设备兼容性、使用场景及听感综合考虑;通过查看设备规格或安卓开发者选项可确认支持的编码格式,iOS默认使用AAC;音质差异主要体现在码率与算法上,LDAC理论音质最佳但对设备要求高;实际音质还受耳机硬件、蓝牙芯片、环境干扰和个人听感影响;若设备不支持高规格编码,可通过优化连接、更换播放器或耳机改善听感;使用高品质编码会增加...

XPath的in-scope-prefixes()函数怎么用?

答案:in-scope-prefixes()函数用于返回当前上下文节点作用域内所有命名空间前缀的序列,帮助诊断命名空间可见性问题。它能揭示XML节点可访问的命名空间前缀(不包括默认命名空间及xml、xmlns),在调试XPath不匹配或处理多命名空间文档时尤为有用,常用于XSLT/XQuery中动态分析命名空间环境,确保正确解析带前缀的元素。 XPath的in-scope-prefixes()函数...

XPath的namespace-uri-from-QName()函数?

namespace-uri-from-QName() 函数用于从 QName 中提取命名空间 URI,其核心作用是解析字符串形式的 QName 并返回对应命名空间地址;当 QName 无前缀或前缀未绑定时返回空序列,常用于动态处理 XML 命名空间验证与解析。 namespace-uri-from-QName() 函数在 XPath 3.1 中,它的核心作用是从一个限定名(QName)中提取出对应...

XPath的document()函数怎么加载外部XML?

首先,确保XPath引擎支持document()函数并正确配置;其次,使用有效URI加载外部XML,如document('departments.xml')关联员工与部门位置;需防范XXE攻击,通过禁用外部实体解析提升安全性;为优化性能,可缓存文档、减少调用次数并采用流式处理。 XPath的document()函数用于加载外部XML文档,这使得我们可以在XPath表达式中访问和处理多个XML文档的...