Puppeteer:如何在没有 CSS/JS/fonts/images 的情况下仅加载 html?

Puppeteer: How to load html only without CSS/JS/fonts/images?

我正在使用 Puppeteer 抓取一些数据,需要在较短的时间内访问很多页面。经过观察,我注意到这是非常低效的,因为我只对标记文件中的数据感兴趣,而包含所有图像、字体和其他内容的整个页面非常慢。因此,如果有一种方法可以跳过其他内容类型并使 Puppeteer return 仅 HTML 文件内容,那就太好了。这是我的代码:

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();

const helperFile = fs.readFileSync("dist/app/scripts/helpers.js", "utf8");
await page.evaluateOnNewDocument(helperFile);

await login(page);
await postLogin(page);
await crawl(page); // this function is gonna call a lot of page.goTo(...)

await browser.close();

您可以拦截来自 Puppeteer 的所有请求,只允许 return 文档的请求 continue() 并丢弃其余请求。

我还决定包含 script 类型,因为 JS 代码可能会修改初始的 DOM 树(类似于 appendChild(node)),如果您使用带有现代 FW/library 的 SPA,例如 React,其中服务器仅 return 几个 JS 包以在客户端中生成 HTML。 scriptfetch 类型存在,以防 JS 代码向服务器发出额外请求以获取更多数据并更新 DOM 树。

import puppeteer, { Page, PageEmittedEvents } from "puppeteer";

const htmlOnly = async (page: Page) => {
  await page.setRequestInterception(true); // enable request interception

  page.on(PageEmittedEvents.Request, (req) => {
    if (!["document", "xhr", "fetch", "script"].includes(req.resourceType())) {
      return req.abort();
    }
    req.continue();
  });
};
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();

await htmlOnly(page);