使用 Javascript Puppeteer 获取标签的内部文本
Get inner text of tags using Javascript Puppeteer
我是 js 的新手,一直在尝试获取 bio__name__display
标签的内部文本(参见附件 DOM),但我失败了。
这可能是什么问题?
我正在从 index.js 调用 page.js 中定义的异步函数,当我 console.log
第一个函数的 return 值,它工作正常。但是第二个函数不起作用(输出为 undefined
)。
对于 CSS 选择器,我尝试了以下但无济于事。
div.bio__name > span.bio__name__display
"div.bio__name>span.bio__name__display"
div.bio__name span.bio__name__display
index.js
const splinterlandsPage= require('./page');
.
.
.
await page.waitForTimeout(10000);
let [mana, displayName] = await Promise.all([
splinterlandsPage.checkMatchMana(page).then((mana) => mana).catch(() => 'no mana'),
splinterlandsPage.getText(page).then((displayName) => displayName).catch(() => 'displayName name not caught')
]);
console.log("mana : ", mana) //works
console.log("displayName: ", displayName); //does not work
.
.
.
page.js
.
.
.
// first function
async function checkMatchMana(page) {
const mana = await page.$$eval("div.col-md-12 > div.mana-cap__icon", el => el.map(x => x.getAttribute("data-original-title")));
const manaValue = parseInt(mana[0].split(':')[1], 10);
return manaValue;
}
// second function
async function getText(page) {
const displayName= await page.$$eval("div.bio__name > span.bio__name__display", el => el.innerText);
return displayName
}
.
.
.
exports.checkMatchMana = checkMatchMana;
exports.getText= getText;
DOM
虽然我很想分享实际的网站 URL,但这样做很难,因为访问 DOM 需要注册该网站,而且这个特定的 DOM 在单击站点内的某个按钮后仅 2 分钟可用。
我今天终于自己弄明白了 - 下面是一个解决方案和一些注释供以后参考。
解决方案
问题不是 CSS 选择器而是 什么 $$eval
returned.
由于 $$eval
return 是一个元素列表,因此必须像 el => el.map(x => x.innerText))
一样处理 return 值,而不是 el => el.innerText
。
page.js
// second function
async function getText(page) {
const displayName = await page.$$eval("div.bio__name > span.bio__name__display", el => el.map(x => x.innerText));
return displayName[0]
}
其他解决方法可以使用 $eval
而不是 return 单个匹配元素。
// second function
async function getText(page) {
const displayName = await page.$eval("div.bio__name > span.bio__name__display", el => el.innerText);
return displayName
}
备注
$$eval
和 $eval
$$eval
runs document.querySelectorAll('CSS Selector') internally, which returns multiple elements 匹配指定的选择器组。
(当只有一个元素匹配时也有效,但 return 值需要在 pageFunction[, ...args]
中进行相应处理)
$eval
runs document.querySelector('CSS Selector') internally, which returns a single element 匹配指定的选择器组。
CSS 选择器
作为新手,我经常发现自己在选择正确的选择器时迷失了方向。
可能是一种快速而肮脏的方式,但 the first answer to this question 有所帮助。
我是 js 的新手,一直在尝试获取 bio__name__display
标签的内部文本(参见附件 DOM),但我失败了。
这可能是什么问题?
我正在从 index.js 调用 page.js 中定义的异步函数,当我 console.log
第一个函数的 return 值,它工作正常。但是第二个函数不起作用(输出为 undefined
)。
对于 CSS 选择器,我尝试了以下但无济于事。
div.bio__name > span.bio__name__display
"div.bio__name>span.bio__name__display"
div.bio__name span.bio__name__display
index.js
const splinterlandsPage= require('./page');
.
.
.
await page.waitForTimeout(10000);
let [mana, displayName] = await Promise.all([
splinterlandsPage.checkMatchMana(page).then((mana) => mana).catch(() => 'no mana'),
splinterlandsPage.getText(page).then((displayName) => displayName).catch(() => 'displayName name not caught')
]);
console.log("mana : ", mana) //works
console.log("displayName: ", displayName); //does not work
.
.
.
page.js
.
.
.
// first function
async function checkMatchMana(page) {
const mana = await page.$$eval("div.col-md-12 > div.mana-cap__icon", el => el.map(x => x.getAttribute("data-original-title")));
const manaValue = parseInt(mana[0].split(':')[1], 10);
return manaValue;
}
// second function
async function getText(page) {
const displayName= await page.$$eval("div.bio__name > span.bio__name__display", el => el.innerText);
return displayName
}
.
.
.
exports.checkMatchMana = checkMatchMana;
exports.getText= getText;
DOM
虽然我很想分享实际的网站 URL,但这样做很难,因为访问 DOM 需要注册该网站,而且这个特定的 DOM 在单击站点内的某个按钮后仅 2 分钟可用。
我今天终于自己弄明白了 - 下面是一个解决方案和一些注释供以后参考。
解决方案
问题不是 CSS 选择器而是 什么 $$eval
returned.
由于 $$eval
return 是一个元素列表,因此必须像 el => el.map(x => x.innerText))
一样处理 return 值,而不是 el => el.innerText
。
page.js
// second function
async function getText(page) {
const displayName = await page.$$eval("div.bio__name > span.bio__name__display", el => el.map(x => x.innerText));
return displayName[0]
}
其他解决方法可以使用 $eval
而不是 return 单个匹配元素。
// second function
async function getText(page) {
const displayName = await page.$eval("div.bio__name > span.bio__name__display", el => el.innerText);
return displayName
}
备注
$$eval
和 $eval
$$eval
runs document.querySelectorAll('CSS Selector') internally, which returns multiple elements 匹配指定的选择器组。
(当只有一个元素匹配时也有效,但 return 值需要在pageFunction[, ...args]
中进行相应处理)$eval
runs document.querySelector('CSS Selector') internally, which returns a single element 匹配指定的选择器组。
CSS 选择器
作为新手,我经常发现自己在选择正确的选择器时迷失了方向。
可能是一种快速而肮脏的方式,但 the first answer to this question 有所帮助。