前景:
通常我们在使用爬虫爬取一些图片的资源并下载到我们本地的时候,总会发现存在一些图片下载下来是打不开的,这类图片一般都是损坏的了,我们一般可以通过自己手动去找到这些图片并去删除它,但是如果是成千上万的图片的话,这种方式就不靠谱了,所以我们肯定是通过代码的方式去自动帮我们检测到并删除它的,下面就说一下我是怎么解决的?
使用Nodejs爬取图片
接口我们使用别人已经提供好的接口来爬取就行了,首先我们在本地新建一个文件夹,使用npm init 初始化我们的文件夹,初始化会生成一个package.json
的文件,我们再新建一个 index.js
文件,然后我们写一个load的函数
接口地址: http://service.picasso.adesk.com/v1/vertical/category/4e4d610cdf714d2966000000/vertical
4e4d610cdf714d2966000000
: 表示分类的id,具体可以看一下这个json文件: https://vkceyugu.cdn.bspapp.com/VKCEYUGU-78abecd5-154a-4bdc-90ef-f4959377f1bc/449eae83-a701-4f3c-9f85-b7902ec42fca.json
在 index.js
导入我们要用到的库
const download = require('download');
const axios = require('axios');
const fs = require('fs');
const _ = require('lodash');
const jimp = require('jimp');
// 开始爬取资源时,我们要稍微伪造设置一下请求头,让浏览器认为我们的请求时正常的请求
let headers = {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
};
// load 函数
async function load(start = 0,imgId) {
const data = await axios
.get(`http://service.picasso.adesk.com/v1/vertical/category/4e4d610cdf714d2966000000/vertical`, {
headers,
params: {
first: 1,
skip:start,
limit:30,// 每页固定返回30条
order: "new",
adult:false
}
})
.then((res) => {
if(res?.data?.code === 0){
// console.log(res.data.res.vertical,'res...')
return res.data.res.vertical;
}
})
.catch((err) => {
console.log(err);
});
await downloadFile(data)
}
// downloadFile 函数,将图片资源下载到我们的本地
async function downloadFile(data) {
for (let index = 0; index < data.length; index++) {
const item = data[index];
// 文件存放的目录
const filePath = `${__dirname}/demo`;
await download(item.wp, filePath, {
filename: item.id + '.jpeg',
headers
}).then(() => {
console.log(`Download ${item.id} Completed`);
return;
});
}
}
// 调用load()函数
load();
上面的几个函数都写好后,我们就可以运行起来了,我们在根目录运行当前命令 node index.js
,效果如下
如果发现有些图片打开时显示这样的,我们就要去删掉它
使用jimp 库检测损坏的图片并删除
我们在 index.js
里面在写一个filter方法,找到文件夹下面所有的图片检测损坏的图片并删除它
// 去除损坏的图片文件
async function readAllFileFilter(){
// 你图片下载存放的目录,我的是根目录下的demo目录下
const filePath = `${__dirname}/demo`;
// 读取文件下的文件,得到所有的文件数组(files)
fs.readdir(filePath,(err,files) => {
// 循环数组
_.map(files,(item) => {
// item 文件名 xxxx.png,使用jimt读取的一个方法,如果存在err则表示图片读取不了(损坏的)
jimp.read(`${filePath}/${item}`,(err) => {
if(err){
console.log(item,'item...')
// 删除损坏的文件
fs.unlink(`${filePath}/${item}`, (err) => {
if (err) throw err;
console.log('成功删除:' + item);
});
}
})
})
})
}
// 调用load()函数
load();
// 调完load()方法再运行我们的readAllFileFilter()函数
readAllFileFilter();
最后我们看一下效果