Xpath的问题:为什么在DOM中确定存在(可见)的元素,用//表达式匹配不到(附解决办法)

发布时间:2024年01月05日

今天遇到一个很有意思的问题,我的爬取的目标页面上有时会出现一个弹窗,它挡住我点击其它按钮了,我想找到它的关闭按钮,自动点击一下关闭掉,本来是很简单的事情,但偏偏出问题了,DOM中看到的html是这样的:

<button id="ember213" class="msg-overlay-bubble-header__control artdeco-button artdeco-button--circle artdeco-button--1 artdeco-button--primary ember-view">
 <svg role="none" aria-hidden="true" class="artdeco-button__icon " xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" data-supported-dps="16x16" data-test-icon="close-small"><!---->
   <use href="#close-small" width="16" height="16"></use>
 </svg>
 <span class="artdeco-button__text"> Close your conversation with {0} and Elise Tolliver</span>
</button>

看起来很简单对吧,我习惯先在控制台试一下,于是写了

$x('//use[@href="#close-small"]')

发现匹配结果竟然是空的。

我的第一反应是会不会是自定义的元素不能直接匹配,查了资料说是没问题的,然后查了很多资料,发现可能跟命名空间有关系,像上面这个就是因为svg元素定义了xmlns属性,所以浏览器认为它不是全局变量,所以无法用全局表达式//来匹配,但这种元素要怎样匹配呢?
有两种情况,
1、在匹配时加上准确的命名空间,还是上面的dom为例,可以这样匹配,这种情形适合有多个不同命名空间的情形:

$x('//*[local-name()="svg" and namespace-uri()="http://www.w3.org/2000/svg"]')

2、还有一种简化的写法,就是直接用local-name()方法匹配(适合不需要区分命名空间的情形):

$x('//*[local-name()="svg"]')

所以最终我的表达式是:

$x('//*[local-name()="use" and @href="#close-small"]')

这样就能准确地找到这个关闭按钮了。
如果本文对你有帮助,请点赞支持一下,谢谢!

文章来源:https://blog.csdn.net/one_and_only4711/article/details/135406204
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。