如何使用axios结合cheerio写一个网页图片爬虫
axios
库是一个极为常用的HTTP客户端库,主要功能就是发送各种HTTP请求,像常见的GET
请求用于获取数据、POST
请求用于提交数据等,并且能很好地处理服务器返回的响应结果。利用axios
,咱们可以打造一个简单的爬虫程序,实现抓取网页内容、提取其中的图片并下载到本地的功能。下面就来详细讲讲具体的操作步骤。
一、安装Axios库
在使用axios
编写爬虫程序之前,得先把它安装到你的项目里。如果你用的是Node.js项目,借助npm这个包管理工具就能轻松完成安装。在项目的命令行里输入下面这条命令:
npm install axios
执行完这条命令,axios
库就安装好了,你可以在项目里使用它了。
二、编写爬虫代码
假设现在有个需求,要抓取某个网页上的图片。下面这段代码展示了如何借助axios
发送HTTP请求,进而下载网页上的图片。
// 引入axios库,用于发送HTTP请求获取网页数据 const axios = require('axios'); // 引入fs模块,它提供了文件操作的相关方法,这里用于保存下载的图片到本地 const fs = require('fs'); // 引入path模块,主要用来处理文件路径,比如拼接路径、获取文件名等 const path = require('path'); // 引入cheerio库,它能像在浏览器里操作DOM一样解析HTML内容,方便提取网页中的元素 const cheerio = require('cheerio'); // 定义下载图片的函数,接收图片的URL和保存时的文件名作为参数 async function downloadImage(imageUrl, filename) { // 创建一个可写流,用于将图片数据写入到指定的文件中 const writer = fs.createWriteStream(filename); // 发送GET请求获取图片数据,以流的方式处理响应 const response = await axios({ url: imageUrl, method: 'GET', responseType:'stream' }); // 将响应的数据流管道到文件写入流,实现将图片数据写入文件 response.data.pipe(writer); // 返回一个Promise对象,在文件写入完成时,通过resolve来标记成功;若出现错误,则用reject标记失败 return new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); }); } // 定义抓取网页并下载所有图片的函数,接收要抓取的网页URL作为参数 async function crawlAndDownloadImages(url) { try { // 发送GET请求获取网页内容 const response = await axios.get(url); // 获取响应中的网页HTML数据 const html = response.data; // 使用cheerio解析网页内容,$就像是在浏览器里操作DOM的jQuery对象,方便获取网页元素 const $ = cheerio.load(html); // 获取网页中所有的<img>标签 const imgTags = $('img'); // 用于存储图片URL的数组 const imageUrls = []; // 遍历所有的<img>标签 imgTags.each((index, img) => { // 获取每个<img>标签的src属性,即图片的URL const imgUrl = $(img).attr('src'); if (imgUrl) { // 判断图片URL是否是相对路径 if (!imgUrl.startsWith('http')) { // 如果是相对路径,利用URL对象将其转换为绝对路径 const parsedUrl = new URL(imgUrl, url); imageUrls.push(parsedUrl.href); } else { // 如果是绝对路径,直接添加到图片URL数组中 imageUrls.push(imgUrl); } } }); // 遍历图片URL数组,下载每一张图片 for (let i = 0; i < imageUrls.length; i++) { const imageUrl = imageUrls[i]; // 获取图片的文件名 const imageName = path.basename(imageUrl); console.log(`下载图片: ${imageUrl}`); // 下载图片并保存到本地的downloads文件夹中 await downloadImage(imageUrl, path.join(__dirname, 'downloads', imageName)); console.log(`图片下载完成: ${imageName}`); } } catch (error) { // 如果在抓取或下载过程中出现错误,打印错误信息 console.error('爬虫出错:', error); } } // 设置要抓取的网页URL,这里需要替换成真实的网址 const url = 'https://example.com'; // 启动爬虫程序,开始抓取网页图片并下载 crawlAndDownloadImages(url);
三、代码解析
(一)安装依赖
axios
:主要负责发送HTTP请求,从指定的网页获取数据,就像是浏览器向服务器索要网页内容一样。cheerio
:能把网页的HTML内容解析成类似DOM树的结构,让开发者可以像操作浏览器中的DOM元素那样,轻松获取和处理网页里的各种元素。fs
:专门用于文件操作,在这个爬虫程序里,它的作用是把下载的图片保存到本地磁盘上。path
:处理文件路径相关的操作,比如拼接保存图片的路径,确保图片能正确保存到指定位置。
(二)downloadImage函数
这个函数的主要任务就是下载图片。它接收图片的URL和保存时的文件名这两个参数。在函数内部,先创建一个文件写入流,用来保存图片数据。然后通过axios
发送GET
请求获取图片数据,并且以流的方式处理响应结果。最后利用pipe
方法把响应的数据流写入到文件中,通过Promise
来处理下载完成或出错的情况。
(三)crawlAndDownloadImages函数
该函数负责抓取网页并下载其中的所有图片。首先,它发送HTTP请求获取网页的HTML内容。接着,用cheerio
解析HTML,找到所有的<img>
标签,提取出图片的URL。对于相对路径的图片URL,会将其转换为绝对路径。最后,遍历所有的图片URL,调用downloadImage
函数把图片下载并保存到本地的downloads
文件夹中。
(四)图片URL处理
在提取图片URL时,如果遇到相对路径的URL,程序会利用new URL(imgUrl, url)
把它转换为绝对路径。这是因为相对路径在不同的网页环境下可能会找不到对应的图片资源,转换成绝对路径后就能确保正确获取图片了。
(五)图片下载与运行爬虫
使用axios
发送HTTP请求以流的形式下载图片,这种方式能提高下载效率,避免一次性加载大量数据。最后,调用crawlAndDownloadImages(url)
启动爬虫程序,传入要抓取的网页URL,程序就会自动抓取网页上的图片并保存到本地。
四、执行爬虫程序
- 在项目目录下新建一个
index.js
文件,把上面编写的代码复制粘贴进去。 - 在命令行中进入项目目录,执行下面的命令来启动爬虫程序:
node index.js
- 程序运行后,会自动下载网页中的所有图片,并保存到当前目录下的
downloads
文件夹里。如果downloads
文件夹不存在,程序会自动创建。
五、总结
通过axios
和cheerio
这两个工具,我们可以快速编写一个简单的爬虫程序,实现抓取网页图片并下载保存的功能。axios
负责与服务器进行数据交互,发送HTTP请求获取网页数据;cheerio
则专注于解析网页内容,提取我们需要的图片URL。这个程序不仅能处理相对路径的图片URL,还能把下载的图片有序地保存到本地。如果有进一步的需求,比如抓取其他类型的资源,或者实现更复杂的爬取逻辑,都可以在这个基础上进行扩展。