在以编程方式单击之前,必须手动单击搜索按钮

Have to manually click on the search button before clicking programmatically

提问人:Bhaumik Bhatt 提问时间:11/1/2023 更新时间:11/1/2023 访问量:39

问:

我正在尝试创建一个简单的 JS 函数,该函数在 youtube 上搜索给定的字符串并返回第一个结果。我计划在已打开 youtube 的选项卡的控制台中运行它。这是我的代码

const fetchLink = ()=>{
    allInputs = document.getElementsByTagName("input")
    allInputs[0].value="Live Fast"
    
    // Fetch button
    document.getElementById("search-icon-legacy").click()
}

我在浏览器中打开 youtube.com,将此函数放在控制台中并调用它。它确实将值放在搜索框中,但不会在第一时间调度单击事件。现在,如果我手动单击搜索按钮,它就会搜索,然后代码运行良好,包括这一行。

// Fetch button
document.getElementById("search-icon-legacy").click()

无法理解为什么脚本在第一次尝试时无法按预期工作,但在第一次尝试后工作得很好。

javascript dom youtube

评论

1赞 Rory McCrossan 11/1/2023
我不确定这一点,但它可能类似于浏览器如何限制媒体在没有用户交互的情况下首先在 DOM 中播放。换句话说,你不能“假装”点击一个链接,除非用户首先通过与页面交互来显示查看页面的意图。如果是这种情况,这是浏览器级别的安全功能,您对此无能为力。
0赞 fritz craft 11/1/2023
你可以使用像 Node.js 的 Puppeteer 这样的网络爬虫。这些实际上可以模拟用户点击
0赞 Bhaumik Bhatt 11/1/2023
当然,但如果可能的话,我仍然想使用 JS 来做

答:

1赞 Alireza Aghaee 11/1/2023 #1

要找出发生这种情况的原因,请在 youtube 打开时在控制台中按顺序执行以下步骤

1-

const searchButton = document.getElementById("search-icon-legacy")

2-

const logEvent = (e)=>console.log(e)

3-

searchButton.addEventListener('click',logEvent)

定义这些东西后,一次单击“搜索”按钮,一次运行您的代码:

const fetchLink = ()=>{
allInputs = document.getElementsByTagName("input")
allInputs[0].value="Live Fast"

// Fetch button
document.getElementById("search-icon-legacy").click()
}

document.getElementById("search-icon-legacy").click()

您可以在控制台中看到事件日志,它们之间的区别是一个名为 isTrusted 的属性。 Event 接口的 isTrusted 只读属性是一个布尔值,当事件由用户操作生成时为 true,当事件由脚本创建或修改或通过 EventTarget.dispatchEvent() 调度时为 false。链接

最后,我认为 youtub 源代码中有这样的代码,如果事件不受信任,则可以阻止搜索

  if (e.isTrusted) {
      /* do search */
     } else {
      /* return */
   }

评论

0赞 Bhaumik Bhatt 11/4/2023
这是解决问题的一个非常聪明的方法,感谢您的帮助。我现在明白了原因,现在我将尝试解决方法