有没有办法为在刷新或 DOM 位置发生变化时不会获得无效元素的元素生成唯一选择器?

Posted

技术标签:

【中文标题】有没有办法为在刷新或 DOM 位置发生变化时不会获得无效元素的元素生成唯一选择器?【英文标题】:Is there a way to produce unique selector for an element that won't get invalid elements on refresh or if DOM position changes? 【发布时间】:2020-12-11 12:08:47 【问题描述】:

我正在使用 puppeteer 抓取该网站的用户资料。我有一个个人资料链接列表,可用于访问每个个人资料页面并抓取每个用户的 twitter 链接、youtube 链接和其他信息。

示例配置文件

https://www.tradingview.com/u/QuantNomad/ - 有 youtube、twitter、网站,但没有位置 https://www.tradingview.com/u/CryptoRox/ - 有推特、网站但位置但没有 youtube

这是我用来为 twitter、youtube 和网站链接生成唯一选择器的配置文件。

我使用 chrome devtools 来获取唯一选择器,youtube 的选择器看起来像这样

但在我分享的另一个个人资料中,没有 youtube 链接,获取了 twitter 链接,但如果 youtube 链接不存在,我希望它为空。

并非所有用户都有 youtube 链接或 twitter 链接等。因此,这些独特的选择器在不同的配置文件中获取了错误的数据。

我知道选择器只是通过获取第 4 项来完成他们的工作(因为选择器是 a:nth-child(4))但是我怎样才能获得一个仅返回那种数据的唯一选择器,例如 youtube 选择器获取 youtube 链接,如果没有链接,然后它什么也不返回,所以一个。

还要记住,链接可以是随机的,以网站链接为例,每个用户都有不同的网站链接,因此您无法将 href 或 innerText 与预定义的关键字匹配。

【问题讨论】:

【参考方案1】:

对于位置,标记图标所在的前面的<span> 元素有一个非常独特的类tv-profile__title-info-icon--place,因此您可以使用该位置文本节点

const loc = document.querySelector('.tv-profile__title-info-icon--place').nextSibling.textContent;

对于锚元素,您知道它们的 href 属性会有所不同(这就是您想要它的原因吗?),因此您可以将其用作选择器。比如

推特链接:a[href*="://twitter.com/"] YouTube 链接:a[href*="://www.youtube.com/"]

其中一个不匹配的链接将是个人网站链接:

a.tv-profile__title-info-item:not([href*="://twitter.com"]):not([href*="://www.youtube.com"])

【讨论】:

哦,好主意?。但我会再等一会儿,看看是否有其他人有更通用的解决方案。【参考方案2】:

如果外部链接列表是有限的,您可以通过给querySelector 提供外部站点 URL 的一部分来检查它们是否存在:

document.querySelector('.tv-profile__title-info-item[href^="https://www.youtube.com"]')

【讨论】:

不错的弗拉德?。起初正是我的想法,但个人网站链接可以是任何东西,因此我们需要一个更通用的解决方案。

以上是关于有没有办法为在刷新或 DOM 位置发生变化时不会获得无效元素的元素生成唯一选择器?的主要内容,如果未能解决你的问题,请参考以下文章

当数据库发生变化时,你如何管理你的 ORM 层?

当应用的“位置”和“后台应用刷新”权限发生变化时,在后台收到通知

上下文 api 状态发生变化,但在刷新浏览器之前不会反映

Android 解决RecyclerView删除Item导致位置错乱的问题

iOS mapKit在用户当前位置更新时刷新方向

刷新磁盘写缓存