这篇文章主要介绍“怎么使用Node.js开发一个简单图片爬取功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Node.js开发一个简单图片爬取功能”文章能帮助大家解决问题。
正文
node-crawler
是一个轻量级的 node.js
爬虫工具,兼顾了高效与便利性,支持分布式爬虫系统,支持硬编码,支持http前级代理。而且,它完全是由 nodejs
写成,天生支持非阻塞异步IO,为爬虫的流水线作业机制提供了极大便利。同时支持对 DOM
的快速选择(可以使用 jQuery
语法),对于抓取网页的特定部分的任务可以说是杀手级功能,无需再手写正则表达式,提高爬虫开发效率。
安装引入
我们先新建一个项目,在里面创建index.js作为入口文件。
然后进行爬虫库 node-crawler
的安装。
# PNPM
pnpm add crawler
# NPM
npm i -S crawler
# Yarn
yarn add crawler
然后用过 require
引入进去。
// index.js
const Crawler = require("crawler");
创建实例
// index.js
let crawler = new Crawler({
timeout:10000,
jQuery:true,
})
function getImages(uri) {
crawler.queue({
uri,
callback: (err, res, done) => {
if (err) throw err;
}
})
}
从现在我们将开始写一个拿到html页面的图片的方法,crawler
实例化后,在其队列中主要是为了写入链接和回调方法。在每个请求处理完毕后将调这个回调函数。
这里还要说明一下, Crawler
使用了 request
库,所以 Crawler
可供配置的参数列表是 request
库的参数的超集,即 request
库中所有的配置在 Crawler
中均适用。
元素捕获
刚才或许你也看到了 jQuery
这个参数,你猜的没错,它可以使用 jQuery
的语法去捕获 DOM
元素的。
// index.js
let data = []
function getImages(uri) {
crawler.queue({
uri,
callback: (err, res, done) => {
if (err) throw err;
let $ = res.$;
try {
let $imgs = $("img");
Object.keys($imgs).forEach(index => {
let img = $imgs[index];
const { type, name, attribs = {} } = img;
let src = attribs.src || "";
if (type === "tag" && src && !data.includes(src)) {
let fileSrc = src.startsWith('http') ? src : `https:${src}`
let fileName = src.split("/")[src.split("/").length-1]
downloadFile(fileSrc, fileName) // 下载图片的方法
data.push(src)
}
});
} catch (e) {
console.error(e);
done()
}
done();
}
})
}
可以看到刚才通过 $
来完成对请求中 img
标签的捕获。然后我们下面的逻辑去处理补全图片的链接和剥离出名字为了后面可以保存取名用。这里还定义了一个数组,它的目的是保存已经捕获到的图片地址,如果下次捕获发现同一个图片地址,那么就不再重复处理下载了。
以下是掘金首页html用 $("img")
捕获到的信息打印:
下载图片
下载之前我们还要安装一个 nodejs
包—— axios
,是的你没看错,axios
不仅提供给前端,它也可以给后端去使用。但是因为下载图片要把它处理成数据流,所以把 responseType
设置成 stream
。然后才可以用 pipe
方法保存数据流文件。
const { default: axios } = require("axios");
const fs = require('fs');
async function downloadFile(uri, name) {
let dir = "./imgs"
if (!fs.existsSync(dir)) {
await fs.mkdirSync(dir)
}
let filePath = `${dir}/${name}`
let res = await axios({
url: uri,
responseType: 'stream'
})
let ws = fs.createWriteStream(filePath)
res.data.pipe(ws)
res.data.on("close",()=>{
ws.close();
})
}
因为可能图片很多,所以要统一放在一个文件夹下,就要判断有没有这个文件夹如果没有就创建一个。然后通过 createWriteStream
方法来把获取到的数据流以文件的形式保存到文件夹里面。
然后我们可以尝试一下,比如我们捕获用一下掘金首页html下的图片:
// index.js
getImages("https://juejin.cn/")
执行后发现就可以发现已经捕获到静态html里面的所有图片了。
node index.js
关于“怎么使用Node.js开发一个简单图片爬取功能”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。