node.js - 如何使用 Puppeteer 和 JSDOM 下载 HTML、CSS 和 IMG

标签 node.js puppeteer jsdom

我正在尝试使用 Puppeteer 下载任何给定的网页。 我想将 HTML 文件、CSS 源和所有图像下载到本地文件夹(以便稍后能够阅读页面,而无需连接到互联网)。

问题是:

  • 1-我还没有找到如何解析 HTML 文件来检测 CSS 和图像 来源以及如何下载。
  • 2-我还没有弄清楚如何更改这些 Assets 路径并确保 它将指向我的本地文件夹。

到目前为止,我不确定解析“html”常量内容的最佳方法是什么(见下文)。我还没弄清楚如何使用 JSDOM 编辑 html。

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

    const { JSDOM } = jsdom;


    (async () => {
      const url = 'https://stackoverflow.com/questions/54507560/how-to-download-html-css-and-imgs-using-puppeteer';
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto(url, {waitUntil: 'load'});
      const html = await page.content();

      const dom = new JSDOM(html);

      // I'm trying to grab all the img and so to be able to edit the path
      console.log(dom.window.document.querySelectorAll("img"));


      // ^ this is not working it return the following object in my node shell : 
      // NodeList { '0': HTMLImageElement {}, '1': HTMLImageElement {} } 
      // I don't know how to process this object and to grab each image path and then to dl it. I don't know how to edit each path to make it relative to my local folder.

      browser.close();
    })();

更新:我现在尝试使用 JSDOM 解析 HTML。

最佳答案

更改全部 <img src>事件页面中的标签

要更改文档中的所有 img 标签,您需要运行 page.evaluate() 并使用document.querySelectorAll()在那里,在浏览器中。这是一个快速工作片段,用于从文档中的每个图像源中删除域:

(async () => {
  const browser = await puppeteer.launch();

  const url = 'https://stackoverflow.com/questions/54507560/how-to-download-html-css-and-imgs-using-puppeteer';
  const page = await browser.newPage();

  await page.goto(url, {waitUntil: 'load'});

  await page.evaluate(() => {
    var imgs = document.querySelectorAll('img');
    imgs.forEach(function(img){
      let imageSrc = img.getAttribute("src");
      img.setAttribute("src", imageSrc.replace(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)/img, ""));
      console.log(img.getAttribute("src"));
    });
  });  
})();

更改每个图像资源的 URL

这有点复杂。简而言之,你需要拦截浏览器发出的每一个请求,而 continue() 它与修改后的 URL。

同样,这是一个工作片段,它将每个图像资源 URL 替换为我们选择的域:

var newDomain = "https://example.com";

(async () => {
  const browser = await puppeteer.launch({headless: false});

  const url = 'https://stackoverflow.com/questions/54507560/how-to-download-html-css-and-imgs-using-puppeteer';
  const page = await browser.newPage();
  await page.setRequestInterception(true);

  page.on('request', (interceptedRequest) => {
    // Continue if request URL is page URL
    if (interceptedRequest.url() == page.url()) {
      interceptedRequest.continue();
      return;
    }

    // Intercept if request resource is an Image
    if (interceptedRequest.resourceType() == "image") {
      // Replace target domain with the new domain we want
      let newUrl = interceptedRequest.url().replace(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)/img, newDomain);
      console.log(newUrl);
      interceptedRequest.continue({
        url: newUrl,
      });
      return;
    }

    // Continue any other requests
    interceptedRequest.continue();
  })

  await page.goto(url, {waitUntil: 'load'});

})();

关于node.js - 如何使用 Puppeteer 和 JSDOM 下载 HTML、CSS 和 IMG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54507560/

相关文章:

jquery - Zombie Js jQuery null TypeError 'compareDocumentPosition'

node.js - 如何使用 Azure api 启动容器实例?

JavaScript 变量作用域/提升问题

node.js - 在服务器和 Git Repo 上使用应用程序 key 的最佳实践

node.js - 使用 puppeteer 流式传输页面的音频

async.js - 我如何知道 Puppeteer 中的页面是否已关闭

css - 如何将样式表添加到 JSDOM

node.js - Express + Postman,req.body 为空

javascript - Puppeteer page.goTo() 永远不会完成

javascript - 安装 jsdom - Node js 时出现 MS 错误