如何使用 Puppeteer 和 JSDOM 下载 HTML、CSS 和 IMG
How to download HTML, CSS, and IMGs using Puppeteer and JSDOM
我正在尝试使用 Puppeteer 下载任何给定的网页。
我想将 HTML 文件、CSS 源和所有图像下载到本地文件夹(这样以后就可以在不连接到互联网的情况下阅读这些页面)。
问题是:
- 1- 我还没有找到如何解析 HTML 文件来检测 CSS 和图像
来源和下载方法。
- 2-我还没想好如何更改这些资产路径并确保
它将指向我的本地文件夹。
到目前为止,我不确定解析 "html" const 内容的最佳方法是什么(见下文)。我还没想好如何使用 JSDOM 编辑 html。
const puppeteer = require('puppeteer');
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
(async () => {
const url = '
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 = '
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 = '
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'});
})();
点这里。
这是我发现的内置解决方案:
https://github.com/website-scraper/website-scraper-puppeteer
所以这是写在存储库上的代码。
它似乎工作得很好!
const scrape = require('website-scraper');
const PuppeteerPlugin = require('website-scraper-puppeteer');
scrape({
urls: ['https://www.instagram.com/gopro/'],
directory: '/path/to/save',
plugins: [ new PuppeteerPlugin() ]
});
我正在尝试使用 Puppeteer 下载任何给定的网页。 我想将 HTML 文件、CSS 源和所有图像下载到本地文件夹(这样以后就可以在不连接到互联网的情况下阅读这些页面)。
问题是:
- 1- 我还没有找到如何解析 HTML 文件来检测 CSS 和图像 来源和下载方法。
- 2-我还没想好如何更改这些资产路径并确保 它将指向我的本地文件夹。
到目前为止,我不确定解析 "html" const 内容的最佳方法是什么(见下文)。我还没想好如何使用 JSDOM 编辑 html。
const puppeteer = require('puppeteer');
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
(async () => {
const url = '
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 = '
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 = '
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'});
})();
点这里。 这是我发现的内置解决方案: https://github.com/website-scraper/website-scraper-puppeteer 所以这是写在存储库上的代码。 它似乎工作得很好!
const scrape = require('website-scraper');
const PuppeteerPlugin = require('website-scraper-puppeteer');
scrape({
urls: ['https://www.instagram.com/gopro/'],
directory: '/path/to/save',
plugins: [ new PuppeteerPlugin() ]
});