puppeteer page.evaluate querySelectorAll返回空对象

时间:2017-09-23 09:13:22

标签: javascript node.js puppeteer

我正在尝试木偶操作,这是一个可以运行它的示例代码  https://try-puppeteer.appspot.com/

问题是此代码返回一个空对象数组

  

[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{ },{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}, {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{} {},{},{},{},{},{},{},{}]

我有任何错误吗?

const browser = await puppeteer.launch();

const page = await browser.newPage();
await page.goto('https://reddit.com/');

let list = await page.evaluate(() => {
            return Promise.resolve(Array.from(document.querySelectorAll('.title')));
        });
console.log(JSON.stringify(list))

await browser.close();

4 个答案:

答案 0 :(得分:16)

evaluate函数返回的值应该是json serializeable。 https://github.com/GoogleChrome/puppeteer/issues/303#issuecomment-322919968

解决方案是从元素中提取href值并将其返回。

 await this.page.evaluate((sel) => {
        let elements = Array.from(document.querySelectorAll(sel));
        let links = elements.map(element => {
            return element.href
        })
        return links;
    }, sel);

答案 1 :(得分:5)

问题:

page.evaluate()的返回值必须为serializable

根据Puppeteer documentation,它说:

如果传递给page.evaluate的函数返回非Serializable值,则page.evaluate解析为undefined。 DevTools协议还支持传输一些无法通过JSON进行序列化的附加值:-0NaNInfinity-Infinity和bigint文字。

换句话说,您不能将元素从页面DOM环境返回到Node.js环境,因为它们是分开的。

解决方案:

您可以将ElementHandle(这是页面内DOM元素的表示形式)返回到Node.js环境。

使用page.$$()获得一个ElementHandle数组:

let list = await page.$$('.title');

否则,如果要从元素中提取href值并返回它们,则可以使用page.$$eval()

let list = await page.$$eval('.title', a => a.href);

答案 2 :(得分:0)

我会在帮助器文件(可能是CustomPage中创建一个类,并向其中创建一个static函数:

class CustomPage {
  static async build() {
    const browser = await puppeteer.launch({
      headless: false
    });

    const page = await browser.newPage();
}

然后,我将转到编写测试的实际文件,并执行以下操作:

const Page = require("./helpers/page");

let page;

beforeEach(async () => {
  page = await Page.build();
  await page.goto("localhost:3000");
});

afterEach(async () => {
  await page.close();
});

答案 3 :(得分:0)

我遇到了类似的问题,我就这样解决了;

 await page.evaluate(() => 
       Array.from(document.querySelectorAll('.title'), 
       e => e.href));