前景:

通常我们在使用爬虫爬取一些图片的资源并下载到我们本地的时候,总会发现存在一些图片下载下来是打不开的,这类图片一般都是损坏的了,我们一般可以通过自己手动去找到这些图片并去删除它,但是如果是成千上万的图片的话,这种方式就不靠谱了,所以我们肯定是通过代码的方式去自动帮我们检测到并删除它的,下面就说一下我是怎么解决的?

使用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,效果如下 load.png 如果发现有些图片打开时显示这样的,我们就要去删掉它 error.png

使用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();

最后我们看一下效果 delete.png