我安装了 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/