【问题标题】:Get inner text of tags using Javascript Puppeteer使用 Javascript Puppeteer 获取标签的内部文本
【发布时间】:2021-11-12 17:30:48
【问题描述】:

我是 js 新手,一直在尝试获取 bio__name__display 标记的内部文本(请参阅附加的 DOM),但我失败了。 这可能是什么问题?

我从 index.js 调用 page.js 中定义的异步函数,当我 console.log 第一个函数的返回值时,它工作正常。但是第二个函数不起作用(输出为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

【问题讨论】:

  • 请链接到实际站点。在制作$$eval 之前,您是否在使用waitForSelector?实际站点动态地操纵元素,因此如果手头没有实际的、可重现的行为,就无法提供帮助。控制台屏幕截图显示选择器可以工作,但是当 Puppeteer 运行时页面可能不会处于相同的状态。有可能元素不存在或隐藏在框架或阴影 DOM 中——这是任何人的猜测。

标签: javascript html css-selectors puppeteer


【解决方案1】:

尽管我想分享实际的网站 URL,但这样做很困难,因为访问 DOM 需要注册该网站,而这个特定的 DOM 仅在特定时间后 2 分钟内可用点击网站内的按钮。

我今天终于自己弄明白了——下面是一个解决方案和一些注释供以后参考。

解决方案

问题不是 CSS 选择器,而是 $$eval 返回的内容
由于$$eval 返回一个元素列表,所以返回值必须像el => el.map(x => x.innerText)) 那样处理,而不是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 代替它返回单个匹配元素。

// 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

CSS 选择器

作为一个新学习者,我经常发现自己在选择正确的选择器时迷失了方向。
可能是一种快速而肮脏的方式,但the first answer to this question 有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 2017-12-26
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多