likes
comments
collection
share

使用node爬取图片真的超级简单

作者站长头像
站长
· 阅读数 17

为什么忽然想批量下载图片了呢

今天忽然发现同事的的电脑上有非常好看的图片。
刚开始是羡慕他有那么多好看的图片
后来慢慢开始嫉妒了
不行,我也要好看的图片
再加上后端接口一直在报错。
机智的小脑袋决定我也要去网站搜集好看的图片
可是一张的存储太麻烦了。
然后就有了接下来的故事

下载图片的步骤

经过我的瞎鼓捣。发现下载图片许4个步骤
1.发送 http 请求,借助node模块,获取整个网页内容。
2.通过 cheerio 库对网页内容进行分析
3.提取 img 标签中的src属性(通过选择器来实现)
4.借助 download 库进行批量图片下载

服务端渲染的网站下载

// 发送请求使用https模块。 
// 因为目标是网站是https,所以我们要使用https模块
const http = require('https')
// 创建一个请求
let req = http.request('xxx目标网站', res => {
  let dataAllArr = []
  // 开始监听data数据
  res.on('data', chunk => {
    // 把所有的数据放在这个数组中,我们这里是拼接
    dataAllArr.push(chunk)
  })
  // 监听结束
  res.on('end', () => {
    // 对数据进行连接,并且指定格式
    let backData = Buffer.concat(dataAllArr).toString('utf-8')
    console.log('目标网站的html结构',backData)
  })
})
// 发送请求
req.end()

这一步我们获取到的是html结构。
接下来我们获取 所有的img标签
然后提取src

使用node爬取图片真的超级简单

cheerio 库的简单使用

先下载库:npm install cheerio

const cheerio = require('cheerio');
//们需要把HTML document传进去
const $ = cheerio.load('<h2 class="title">Hello world</h2>');
// 赋值显示的内容
$('h2.title').text('Hello there!');
// 添加一个类名
$('h2').addClass('welcome');
// 输出html
$.html();
它将输出如下内容:
<html><head></head><body><h2 class="title welcome">Hello there!</h2></body></html>

输出获取到的每一张图片的src

// 发送请求使用https模块。 
// 因为目标网站是https,所以我们要使用https模块
const http = require('https')
// 引入 cheerio库
const cheerio = require('cheerio')
// 创建一个请求
let req = http.request('目标地址的url', res => {
  let dataAllArr = []
  // 开始监听data数据, 把所有的数据放在这个数组中,我们这里是拼接
  res.on('data', chunk =>  dataAllArr.push(chunk))
  // 监听结束
  res.on('end', () => {
    // 对数据进行连接,并且指定格式
    let backStr = Buffer.concat(dataAllArr).toString('utf-8')
    let $ = cheerio.load(backStr)
    // 通过选择器获取img标签
    $(".article-irl-img img").each(( index,item) => {
      console.log($(item).attr('src'))
    })
  })
})

// 发送请求
req.end()

使用node爬取图片真的超级简单

使用 download 库将输出的图片进行下载

const http = require('https')
// 引入 cheerio库
const cheerio = require('cheerio')
// 引入下载模块
const download = require('download')
// 创建一个请求
let req = http.request('目标地址的url', res => {
  let dataAllArr = []
  // 开始监听data数据, 把所有的数据放在这个数组中,我们这里是拼接
  res.on('data', chunk =>  dataAllArr.push(chunk))
  // 监听结束
  res.on('end', () => {
    // 对数据进行连接,并且指定格式
    let backStr = Buffer.concat(dataAllArr).toString('utf-8')
    let $ = cheerio.load(backStr)
    let imgArr =Array.prototype.map.call(
     $(".article-irl-img img"),item => $(item).attr('src')
    ) 
    Promise.all(imgArr.map(v => download(v, 'imgFile'))).then(() => {
      console.log('all file down finsh')
    })
  })
})

// 发送请求
req.end()

使用node爬取图片真的超级简单

出现 RequestError: Request path contains unescaped characters

在我们下载的时候,如果url中包含中文,将会出现这样
RequestError: Request path contains unescaped characters
为什么会出现这样的情况呢?
因为:http请求是不能够包含中文的,
如果人会说:地址栏有中文也可以正常的请求。
其实你要看network下的地址,绝对是进行了一次的

如何解决这个问题呢?
我们可以使用 encodeURI(imgurl) 来解决这个问题

客户端渲染的如何下载图片呢?

const http = require('https')
// 创建一个请求
// 第一个参数数url
// 第二个参数数一些配置项
// 如:
// auth <string> 用于计算授权标头的基本身份验证 ('user:password')。
// headers <Object> 包含请求头的对象。
// host <string> 要向其发出请求的服务器的域名或 IP 地址。 默认值: 'localhost'。
let req = http.request('url', {method:'POST', }, res => {
  let dataAllArr = []
  // 开始监听data数据
  res.on('data', chunk =>  dataAllArr.push(chunk))
  // 监听结束
  res.on('end', () => {
    // 对数据进行连接,并且指定格式
    let backData = Buffer.concat(dataAllArr).toString('utf-8')
    // 因为目标不同的网站返回来的数据格式不一样,就需要自己单独处理了
    console.log(backData)
  })
})

// 发送请求
req.end()

尾声

如果你觉得我写的不错的话,点一下推荐。 
听说打赏的小哥哥都追到女朋友了,。
咦!你不信,不信你给我打赏看一下! 保准你追到到喜欢的Ta

本文正在参加「金石计划」