node.js - Puppeteer 中的 $x 选择器不能用作 page.evaluate 中的 ElementHandle
问题描述
我正在尝试使用 puppeteer 抓取维基百科页面。我更喜欢对选择器使用 xpath 语法,因为我发现它更强大。
从文档中,它说 the$x
和$
方法都应该返回一个返回数组ElementHandle
的方法。$x
如果我在相关页面的 Chrome 控制台中运行我的两个测试查询,我会得到相同的结果。如果我查询两个选择器而不尝试评估 puppeteer 中的结果,我也会得到相同的结果。
当我尝试使用该evaluate
方法时出现问题,$x 选择器中的 ElementHandle 似乎不正确。但我很难弄清楚我做错了什么。
这是一个代码示例。我将异步方法解构到它们的 .then.catch 中以帮助隔离问题。
const puppeteer = require('puppeteer');
(async() => {
const searchUrl = "https://en.wikipedia.org/wiki/German_national_football_team"
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(searchUrl);
const xPathSelector = page.evaluate(
el => el.outerHTML,
await page.$x("//table[@class='infobox']//th[contains(.,'Head')]/following-sibling::td/a")[0])
.then(
result => console.log(result)
).catch( e => {
console.log('XPath Error', e)
})
const normSelector = await page.evaluate(
el => el.outerHTML,
await page.$("#mw-content-text > div > table:nth-child(2) > tbody > tr:nth-child(5) > td > a"))
.then(
result => console.log(result)
).catch( e => {
console.log('XPath Error', e)
})
await browser.close()
})()
解决方案
在您的第一个示例中,您试图读取未解决的承诺的第一个元素,而不是它的结果,因此,更改:
await page.$x("//table[@class='infobox']//th[contains(.,'Head')]/following-sibling::td/a")[0]
to(查看额外的包装括号):
(await page.$x("//table[@class='infobox']//th[contains(.,'Head')]/following-sibling::td/a"))[0]
推荐阅读
- css - 使用 SASS 从颜色中提取 H、S、L 值
- paypal - 贝宝“CURRENCY_NOT_ALLOWED”
- c# - 加快从远程 URL 检索文件大小
- sql - 在 where 子句中避免 coalesce() 或 case
- javascript - 搜索文本修剪脚本后 livewire 不起作用“...查看更多”
- github-pages - 如何获取 gh 页面的下拉菜单?
- node.js - 为什么 Eclipse 需要 node.js?
- python - 同时运行 asyncio bot 到 Tkinter GUI
- python - 'int' 对象不是 python3 上的可调用问题
- android - 参数必须是数组