Puppeteer:如何下载整个网页以供离线使用

20

我该如何使用Google的Puppeteer爬取整个网站,包括其所有的CSS/JavaScript/媒体资源(而不仅仅是HTML)?在成功地尝试了其他爬虫工作后,我想它应该可以实现。

然而,在查看了许多优秀的在线示例后,没有明显的方法可供使用。到目前为止,我能找到的最接近的方法是调用

html_contents = await page.content()

是否有办法在 Puppeteer 中保存网页以供离线使用,同时保留非 HTML 元素?


1
Puppeteer不会实现这个功能 https://github.com/GoogleChrome/puppeteer/issues/2433 - hardkoded
嗯...这让我感到惊讶,因为我想不出他们为什么不实现这个功能的好理由。无论如何,我希望在这种情况下有人已经制作了第三方扩展程序。 - Coolio2654
1
@hardkoded,有一种实验性的方法,请参见下面的答案。 - vsemozhebuty
嗨,Coolio。请不要在问题中添加对话内容。总的来说,这里的读者更喜欢技术性的写作方式,因为简洁可以增加清晰度。读者会默认感激你的回答,并且最好通过点赞/采纳来表达。 - halfer
我不同意那种说法,因为写作清晰需要一定的轻松感,但既然你是管理员,那就好吧。 - Coolio2654
1个回答

37

目前可以通过实验性的CDP调用'Page.captureSnapshot'并使用MHTML格式进行:

'use strict';

const puppeteer = require('puppeteer');
const fs = require('fs');

(async function main() {
  try {
    const browser = await puppeteer.launch();
    const [page] = await browser.pages();

    await page.goto('https://en.wikipedia.org/wiki/MHTML');

    const cdp = await page.target().createCDPSession();
    const { data } = await cdp.send('Page.captureSnapshot', { format: 'mhtml' });
    fs.writeFileSync('page.mhtml', data);

    await browser.close();
  } catch (err) {
    console.error(err);
  }
})();

1
我会稍等一下,看看是否有人成功地制作了 Puppeteer 的分支版本,可以完美地保存网站以供离线使用,但在此之前感谢您的清晰示例。关于 captureSnapshot 正在得到多少开发方面的消息?正如您自己所暗示的那样,它缺少很多功能,尽管比原始 HTML 复制略好一些。 - Coolio2654
我不了解详情,抱歉。如果这种格式足够的话,那就取决于使用结果的需求。 - vsemozhebuty
我看到很多人使用CDP会话,你能告诉我它的用途和在哪里有用吗? - Raj Saraogi
@RajSaraogi CDP是puppeteer工作基于的协议,因此它提供了比puppeteer的“sugar”API更多的可能性。在这里查看更多信息:https://chromedevtools.github.io/devtools-protocol/ - vsemozhebuty
@vsemozhebuty,在下载了离线页面之后,我该如何使用 Puppeteer 加载它呢?我尝试了 goto('site.mhtml'),但是收到了 Error: net::ERR_ABORTED 的错误提示。 - itaied
1
如果我理解正确,你需要文件的完整绝对路径,例如 file:///path/to/site.mhtml - vsemozhebuty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接