首页 > 解决方案 > 如何将回调作为变量传递给 puppeteer 中的 page.evaluate?

问题描述

更新我在 docker 中运行并使用 puppeteer 版本 1.11.0,因为这是alpine linux 支持的最新版本。我也在跑步--no-sandbox

只是为了代码组织,我想在 puppeteer 中这样做......

async function crawler(url, evaluater) {
    const browser = await puppeteer.launch(...)
    const page = await browser.newPage()
    await page.goto(url)
    const result = await page.evaluate(evaluater)
    return result

}

crawler('https://website.com', () => {
    return document.querySelectorAll(...)
})

但是我收到以下错误....

Error: Evaluation failed: TypeError: Cannot read property 
'querySelectorAll' of undefined

我假设 evaluator 函数实际上被传递给eval所以我希望下面的工作在这种情况下

const result = await page.evaluate(evaluater.toString())

这也不起作用。没有错误信息,但undefined被返回。如果我将函数内联移动,则返回数据。

有什么方法可以提供page.evaluate未内联定义但作为变量传入的回调?

标签: javascriptnode.jspuppeteer

解决方案


您的代码看起来不错,它在我的环境中工作。您的问题可能来自puppeteer版本 - 让我们删除node_modules并重新安装它们,

您的网站您想要抓取的内容已通过某些方式禁用了抓取工具间谍 - 让我们在另一个网站上进行测试。

这是我的代码,你可以在你的环境中尝试:

const puppeteer = require('puppeteer');
async function crawler(url, evaluator) {
  const browser = await puppeteer.launch({
    headless: false,
  });
  const page = await browser.newPage()
  await page.goto(url)
  const result = await page.evaluate(evaluator)
  // await browser.close();
  return result

}

(async () => {
  let result = await crawler('https://google.com', () => {
    const nodes = Array.from(document.querySelectorAll('a'));
    return nodes.map(({ innerText }) => innerText)
  });
  console.log(result);
})();

推荐阅读