javascript - 无法查询 Puppeteer 上的选择器(TypeError : selector.startsWith 不是函数)

标签 javascript node.js puppeteer

我安装了 Puppeteer 并想要查询选择器来处理它。 但我遇到了 TypeError:selector.startsWith is not a function 错误。

我尝试通过添加 toString() 来更改核心代码来修复它,但没有成功。

这是我尝试过的两种表达式:

await page.$eval('#firstName', elem => elem.click());
await page.waitForSelector('#firstName');

两者都不起作用并产生了相同的错误。

我还尝试安装旧的 puppeteer 和 Node 版本,但它仍然相同。 我该如何解决这个问题?

所有错误日志信息为:

file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/GetQueryHandler.js:51
                if (selector.startsWith(prefix)) {
                             ^

TypeError: selector.startsWith is not a function
    at getQueryHandlerAndSelector (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/GetQueryHandler.js:51:30)
    at CDPElementHandle.$ (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/ElementHandle.js:74:51)
    at IsolatedWorld.$ (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/IsolatedWorld.js:126:25)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async IsolatedWorld.focus (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/IsolatedWorld.js:186:24)
    at async file:///C:/Users/User/Desktop/mail/index.js:17:5

产生相同错误的完整代码示例是:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const context = await browser.createIncognitoBrowserContext();
  if (context) {
    const page = await browser.newPage();

    await page.goto('https://accounts.google.com/signup/v2/webcreateaccount?biz=false&cc=TR&dsh=S-519439412%3A1682412535258329&flowEntry=SignUp');
  
    // Set screen size
    await page.setViewport({width: 1080, height: 1024});
    //await page.$eval('#firstName', elem => elem.click());
    const username = await page.waitForSelector('#firstName');
    await page.focus(username)
    await page.keyboard.type('test54')
  }

})();

最佳答案

您需要为 page.focus(selector) 等任何函数的第一个参数传递一个字符串。参数 selector 是您要执行操作的 CSS 或 Puppeteer 选择器。

在下面的代码中,您传递的是 ElementHandle 而不是字符串:

const username = await page.waitForSelector('#firstName');
await page.focus(username);

这会抛出异常,因为 ElementHandles 没有 .startsWith 方法。

有两种可能的解决方案:

const username = await page.waitForSelector('#firstName');
await page.focus('#firstName'); // pass a string

或者,因为您已经有了元素句柄:

const username = await page.waitForSelector('#firstName');
await username.focus(); // call .focus() on the ElementHandle

为了 future 的访问者,以下是一些对 Puppeteer 选择器函数的常见调用,它们也会导致相同的错误:

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

let browser;
(async () => {
  browser = await puppeteer.launch({headless: "new"});
  const [page] = await browser.pages();
  await page.setContent("<p>hi</p>");

  /* any of the following lines throws */

  // ElementHandle
  const handle = await page.$("p");
  await page.focus(handle)
    .catch(err => console.error(err.message, "(handle)"));

  // Promise
  await page.focus(new Promise((res, rej) => {}))
    .catch(err => console.error(err.message, "(promise)"));

  // number
  await page.waitForSelector(42)
    .catch(err => console.error(err.message, "(number)"));

  // func
  await page.$$eval(() => {})
    .catch(err => console.error(err.message, "(func)"));

  // object
  await page.$eval({})
    .catch(err => console.error(err.message, "(object)"));

  // array
  await page.$(["#first-name"])
    .catch(err => console.error(err.message, "(array)"));

  // boolean
  await page.$$(true)
    .catch(err => console.error(err.message, "(boolean)"));

  // null
  await page.click(null)
    .catch(err => console.error(err.message, "(null)"));

  // undefined
  await page.$()
    .catch(err => console.error(err.message, "(undefined)"));
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

输出:

selector.startsWith is not a function (handle)
selector.startsWith is not a function (promise)
selector.startsWith is not a function (number)
selector.startsWith is not a function (func)
selector.startsWith is not a function (object)
selector.startsWith is not a function (array)
selector.startsWith is not a function (boolean)
Cannot read properties of null (reading 'startsWith') (null)
Cannot read properties of undefined (reading 'startsWith') (undefined)

Puppeteer 提供自定义查询选择器,例如 "text/foobar""pierce/p"。当前的 API 首先使用 .startsWith 乐观地检查这些前缀之一是否存在,这是一个仅存在于字符串中的属性。

避免此错误的一种方法是使用 TypeScript。否则,请检查 Puppeteer 文档以了解您尝试调用的方法,以确保您传递了适当的类型。


不相关,但如果您想使用您创建的上下文,await browser.newPage(); 应该是 await context.newPage();

关于javascript - 无法查询 Puppeteer 上的选择器(TypeError : selector.startsWith 不是函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76100164/

相关文章:

javascript - 缓慢循环页面并使用 puppeteer 提取数据

puppeteer - puppeteer 中的默认 Chromium 是否将遥测数据发送给第三方?

javascript - 是否可以从 JavaScript 调用 hamlet?

JavaScript 'strict mode' 没有按预期工作?

linux - 如何在树莓派/或任何基于 Linux 的 PC 上托管 NodeJS http Web 服务器

node.js - 停止回调链并在 Save 方法 ApostropeCMS 之前发送通知

node.js - 使用 Node.js 和 Express 发出 unirest GET 请求

javascript - 如何链接外部Js文件中的公共(public)目录

javascript - 计算器中的正则表达式

node.js - 如何将上下文 Node 添加到 puppeteer 中的 xpath 查询?