nodejs实现简单的图片爬虫

102 阅读2分钟

目标:利用nodejs爬取网页上的所有图片

image.png

目录结构与思路

所需第三方模块:

  1. cheerio:分析这个网页的内

  2. request:请求

整体的思路

通过第三方模块request请求网页地址,从而得到整个网页的DOM结构,根据DOM结构利用cheerio模块分析出图片文件的地址,再次请求这个地址,最后将得到的图片数据储存在本地。

项目目录

image.png

  • img文件夹用来存储图片文件。
  • node_modules文件夹是模块默认的保存位置
  • index.js文件是整个项目的入口文件
  • config.js文件是配置文件,用来放置网页地址和图片文件夹的路径。这样做的目的是使整个项目的可拓展性增强。
  • analyze.js文件用来存储分析DOM的方法。
  • package.json文件是包的描述文件。

步骤

1. 新建一个项目文件夹,进入项目文件夹

2. 初始化 + 下载依赖包

# 初始化项目,会自动生成package.json
npm init

# 下载2个依赖包
npm i request cheerio

3. 根目录下新建config.js配置文件

作用:用来配置网页地址与图片存储的文件夹

import * as path from "path";
import { join } from "path";
// 最新 node 核心包的导入写法
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
// 获取 __filename 的 ESM 写法
const __filename = fileURLToPath(import.meta.url)
// 获取 __dirname 的 ESM 写法
const __dirname = dirname(fileURLToPath(import.meta.url))


// 配置想爬取的网页url
const url = "https://www.hao123.com/?src=from_pc"

const imgDir = join(__dirname, 'imgs')

export  {
  url,
  imgDir
}

4. 新建analyze.js

存储分析DOM的方法。 作用:cheerio模块可以像jQuery一样操作DOM。

# 解析DOM,得到图片地址
import cheerio from "cheerio"

function findImg(dom, callback) {
  let $ = cheerio.load(dom)
  $('img').each(function(i, elem) {
    let imgSrc = $(this).attr('src')
    callback(imgSrc, i)
  })
}

export default findImg

5. 新建index.js作为主模块并请求图片

引入前2个文件,利用request模块请求图片地址,得到DOM结构

import fs from "fs";
import request from "request";
import * as path from "path";
import { url, imgDir } from "./config.js";
import findImg from "./analyze.js";

// 发出请求获取DOM结构,并交给 findImg() 处理
function start() {
  request(url, function (err, res, body) {
    console.log("[ start ] >");
    if (!err && res) {
      findImg(body, downLoad);
    }
  });
}

// 把请求得到的数据写入本地文件夹
function downLoad(imgUrl, i) {
  let ext = imgUrl.split(".").pop();  // 获取图片拓展名
  if (ext == "png" || ext == "jpg" || ext == "jpeg") {  // 判断图片拓展名
    let arr = imgUrl.split('/');   // 根据斜杠切割,获取最后的图片名称:  arr[arr.length-1]   
    request(imgUrl).pipe(
       // 存储图片到本地 imgs 文件夹(config.js中设置的路径),并指定
      fs.createWriteStream(path.join(imgDir, arr[arr.length-1]), {
        encoding: "utf8", // 指定字符集:nodejs通过Buffer存储二进制数据,转为字符串时需要的字符集
      })
    );
    
  }
}

start();  // 运行

6. 启动项目

node index.js

运行完可以在imgs文件夹下看见爬取并保存的图片

附录:

本文参考《Node.js 10实战》,本案例 node 版本为18.15.0