简体   繁体   中英

Get inner text of tags using Javascript Puppeteer

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

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

在此处输入图片说明

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.

Solution

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 .

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]
}

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
}

Notes

$$eval and $eval

CSS 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM