Node.js Puppeteer - 使用 YouTube 搜索输入“错误:评估失败:错误:无法聚焦非 HTMLElement”

问题描述 投票:0回答:2

我正在尝试使用 Puppeteer 输入 YouTube 的搜索输入。

代码如下:

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://youtube.com');
    await page.type('#search','a');
...

这是我得到的错误:

throw new Error('Evaluation failed: ' + (0, util_js_1.getExceptionMessage)(exceptionDetails));
          ^

Error: Evaluation failed: Error: Cannot focus non-HTMLElement
    at pptr://__puppeteer_evaluation_script__:3:23
    at ExecutionContext._ExecutionContext_evaluate (/Users/benjaminrubin/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:286:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ExecutionContext.evaluate (/Users/benjaminrubin/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:117:16)
    at async ElementHandle.evaluate (/Users/benjaminrubin/node_modules/puppeteer/lib/cjs/puppeteer/common/JSHandle.js:105:16)
    at async ElementHandle.focus (/Users/benjaminrubin/node_modules/puppeteer/lib/cjs/puppeteer/common/ElementHandle.js:486:9)
    at async ElementHandle.type (/Users/benjaminrubin/node_modules/puppeteer/lib/cjs/puppeteer/common/ElementHandle.js:516:9)
    at async DOMWorld.type (/Users/benjaminrubin/node_modules/puppeteer/lib/cjs/puppeteer/common/DOMWorld.js:449:9)
    at async /Users/benjaminrubin/Documents/Software Dev Education/Scraping with Node JS/youtubeScrape.js:60:9

我不知道到底出了什么问题。网络上的几个示例使用完全相同的格式。 “无法聚焦非 HTMLElement”到底是什么意思?

javascript node.js web-scraping youtube puppeteer
2个回答
2
投票

这是一个棘手的问题。 Google 网站因违反“一页上有一个 id”规则而臭名昭著,因此实际上有两个具有 id 的元素

search
:

<ytd-searchbox id="search"> <!-- the one you are actually selecting -->
    ... bunch of nodes ...
    <input id="search"> <!-- the one you think you're selecting -->

await page.type('#search','a');
输入
ytd-searchbox
,这不是标准 HTML 元素,因此 Puppeteer 会失败并出现
Error: Cannot focus non-HTMLElement
错误。

解决方法是使用

input#search
代替:

const puppeteer = require("puppeteer"); // ^19.1.0

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.goto("https://youtube.com", {waitUntil: "domcontentloaded"});
  await page.type("input#search", "hello world");
  await page.screenshot({path: "youtube.png"});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

虽然上述解决方案可能有效,但这是一个很好的示例,说明只需将搜索编码为 URL 参数并直接导航到结果页面会更轻松、更高效:

const puppeteer = require("puppeteer");

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const q = encodeURIComponent("your search here");
  const url = `https://www.youtube.com/results?search_query=${q}`;
  await page.goto(url, {waitUntil: "networkidle2"});
  await page.screenshot({path: "youtube.png"});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

0
投票

完成...

© www.soinside.com 2019 - 2024. All rights reserved.