我需要从一些网站上获取大量图像并将它们下载到磁盘上,以便可以使用它们(将它们上传到Blob(azure),然后将链接保存到我的数据库中)。
我知道如何使用JS从html获取图像,例如,其中一个我将进行for循环并执行:
document.getElementsByClassName('person')[i].querySelector('div').querySelector('img').getAttribute('src')
在那里,我将拥有所有图像的链接。
我还看到我可以通过执行以下操作使用node和fs模块将文件保存到磁盘:
function saveImageToDisk(url, localPath) {var fullUrl = url;
var file = fs.createWriteStream(localPath);
var request = https.get(url, function(response) {
response.pipe(file);
});
}
这是我遇到的问题,我不知道如何确切地连接两个部分(脚本和nodejs代码),我想获取图像以及图像名称(在这种情况下为alt标记),然后在节点中使用它们将图像上传到Blob,并将它们的名称和图像Blob URL放入我的数据库中。
我以为我可以下载html页面,然后将JS脚本放在主体底部,但是后来我不知道如何将URL传递给nodejs代码。
我该怎么做?
我不太习惯使用脚本,我经常使用没有它们的节点,我对它们的交互以及如何将js脚本连接到我的代码感到困惑。
这也是解决此问题的最佳方法吗?还是我没有看到更简单/更好的方法?
谢谢
答案 0 :(得分:1)
我建议您使用dom-parser
模块。看到这里:https://www.npmjs.com/package/dom-parser
这样做,您可以使用http.get()
下载整个html文件,并使用dom-parser
对其进行解析。然后从HTML文件中提取您需要的所有信息。使用图片网址,使用您的saveImageToDisk()
函数。
按照您的想法,您必须如上所述将JS脚本添加到html文件中。但除此之外,您还必须使用Ajax(xmlHttpRequest
)将URL发布到nodeJS服务器。
答案 1 :(得分:1)
感觉您应该使用搜寻器。以下代码应该可以工作(使用npm模块crawler):
const Crawler = require("crawler")
const c = new Crawler({
callback: function(error, res, done) {
if (error) {
console.log({error})
} else {
const images = res.$('.person div img')
images.each(index => {
// here you can save the file or save them in an array to download them later
console.log({
src: images[index].attribs.src,
alt: images[index].attribs.alt,
})
})
}
}
})
c.queue('https://www.yoursite.com')
答案 2 :(得分:1)
您需要在Web API(用于DOM解析等)和Node.js API之间建立桥梁。例如,Node.js的一些无头浏览器管理工具。说,您可以在此脚本中使用puppeteer:
'use strict';
const puppeteer = require('puppeteer');
const https = require('https');
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/Image');
const imgURLs = await page.evaluate(() =>
Array.from(
document.querySelectorAll('#mw-content-text img.thumbimage'),
({ src }) => src,
)
);
console.log(imgURLs);
await browser.close();
imgURLs.forEach((imgURL, i) => {
https.get(imgURL, (response) => {
response.pipe(fs.createWriteStream(`${i++}.${imgURL.slice(-3)}`));
});
});
} catch (err) {
console.error(err);
}
})();
您甚至可以使用浏览器已经下载的图片下载一次图像。该脚本可保存相同的图像,但具有一个请求会话,而无需使用https
Node.js模块(这样可以节省时间,网络流量和服务器工作量):
'use strict';
const puppeteer = require('puppeteer');
const fs = require('fs');
(async function main() {
try {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
const allImgResponses = {};
page.on('response', (response) => {
if (response.request().resourceType() === 'image') {
allImgResponses[response.url()] = response;
}
});
await page.goto('https://en.wikipedia.org/wiki/Image');
const selecedImgURLs = await page.evaluate(() =>
Array.from(
document.querySelectorAll('#mw-content-text img.thumbimage'),
({ src }) => src,
)
);
console.log(selecedImgURLs);
let i = 0;
for (const imgURL of selecedImgURLs) {
fs.writeFileSync(
`${i++}.${imgURL.slice(-3)}`,
await allImgResponses[imgURL].buffer(),
);
}
await browser.close();
} catch (err) {
console.error(err);
}
})();
答案 3 :(得分:0)
您可以使用Promise
并在其中执行获取所有图像并将图像url放入数组的工作。然后在then方法内可以迭代数组并调用saveImageToDisk
每次,也可以通过修改幻灯片将数组发送到中间层。第二种方法更好,因为它只会打一个网络电话
function getImages() {
return new Promise((resolve, reject) => {
// Array.from will create an array
// map will return a new array with all the image url
let k = Array.from(document.getElementsByClassName('person')[0].querySelector('div')
.querySelectorAll('img'))
.map((item) => {
return item.getAttribute('src')
})
resolve(k)
})
}
getImages().then((d) => {
// it will work only after the promise is resolved
console.log('****', d);
(item => {
// call saveImageToDisk function
})
})
function saveImageToDisk(url, localPath) {
var fullUrl = url;
var file = fs.createWriteStream(localPath);
var request = https.get(url, function(response) {
response.pipe(file);
});
<div class='person'>
<div>
<img src='https://www.fast-growing-trees.com/images/P/Leyland-Cypress-450-MAIN.jpg'>
<img src='http://cdn.shopify.com/s/files/1/2473/3486/products/Cypress_Leyland_2_Horticopia_d1b5b63a-8bf7-4897-96fb-05320bf3d81b_grande.jpg?v=1532991076'>
<img src='https://www.fast-growing-trees.com/images/P/Live-Oak-Tree-450w.jpg'>
<img src='https://www.greatgardenplants.com/images/uploads/452_1262_popup.jpg'>
<img src='https://shop.arborday.org/data/default/images/catalog/600/Turnkey/1/Leyland-Cypress_3-828.jpg'>
<img src='https://images-na.ssl-images-amazon.com/images/I/51RZkKnrlSL._SX425_.jpg'>
<img src='https://thumbs-prod.si-cdn.com/Z3JYiuJ96ReLq04NCT1B94sTd4E=/800x600/filters:no_upscale()/https://public-media.si-cdn.com/filer/06/9c/069cfb16-c46c-4742-85f0-3c7e45fa139d/mar2018_a05_talkingtrees.jpg'>
</div>