I am new to js and have been trying hours getting inner text of bio__name__display
tag (see the attached DOM) and I am failing. What could be the problem here?
I am calling async functions defined in page.js from index.js , and when I console.log
the return value of a first function, it works fine. However the second function does not work (the output is undefined
).
For CSS Selector, I tried the following but to no avail.
div.bio__name > span.bio__name__display
"div.bio__name>span.bio__name__display"
div.bio__name span.bio__name__display
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
.
.
.
.
.
.
// 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;
As much as I wanted to share the actual site URL, it was tough to do so since the access to the DOM required a sign-up for the site and this specific DOM in question is available for only 2 minutes after a certain button within the site is clicked.
I finally figured them out myself today - below is a solution and some notes for later reference.
The issue was not a CSS Selector but what $$eval
returned .
Since $$eval
returns a list of elements, the return value has to be processed like el => el.map(x => x.innerText))
instead of el => el.innerText
.
// 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]
}
Other workaround can be using $eval
instead which returns a single matching element.
// second function
async function getText(page) {
const displayName = await page.$eval("div.bio__name > span.bio__name__display", el => el.innerText);
return displayName
}
$$eval
and $eval
$$eval
runs document.querySelectorAll('CSS Selector') internally, which returns multiple element s that match the specified group of selectors.
( Also works when there's only a single element that matches, but the return value needs to be processed accordingly in pageFunction[, ...args]
)
$eval
runs document.querySelector('CSS Selector') internally, which returns a single element that matches the specified group of selectors.
As a new learner, I often find myself lost getting my head around choosing right Selectors.
Might be a quick and dirty way but the first answer to this question helped.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.