- 需求
爬取守望先锋官网主页面的英雄图片和英雄图标
通过观察页面源代码, 发现主页面的英雄信息不能直接通过源代码获取到, 而是以json的格式保存保存的, 通过访问该文件的链接, 来对主页面进行渲染, 所以可以通过访问该json数据的链接来获得图片的下载链接, 然后进行下载
- 源代码如下:
// 第三方模块 请求网页数据
const axios = require('axios')
// 核心模块 操作文件流
const fs = require('fs')
// 核心模块 操作文件路径
const path = require('path')
// 爬取地址
const httpUrl = 'https://overwatch.nosdn.127.net/1/data/homeHeroes-20200416.json?callback=heroesJson&_=1605525107098'
// 全局变量 用于查看爬取图片个数
let index = 0
/**
* 下载图片异步函数
* @param {*} imgType 图片类型 icon/img
* @param {*} hero 英雄对象 包括名称 链接
*/
async function downloadImg(imgType, hero) {
// 获取 图片名称
let name = hero.name
// 根据图片类型 获取下载链接
let url = imgType === 'icon' ? hero.iconUrl : hero.imgUrl
// 获取图片后缀名
let extName = path.parse(url, true).ext
// 通过正则将图片名称中的中文引号删除掉
if(name.includes('”')) {
name = name.replace(/[“”]/g, ele => '')
}
// 创建输出流
let ws = fs.createWriteStream(`./image/${imgType}/${name+extName}`)
// 创建输入流
let res = await axios.get(url, {responseType: 'stream'})
// 将输入流连接到输出流
res.data.pipe(ws)
// 输入流关闭时 关闭输出流
res.data.on('close', () => {
ws.close()
})
// 提示图片已下载完成
console.log(`${++index}\.${imgType}类型 ${name+extName} 下载完成...\n`)
}
/**
* 立即执行异步函数(主函数)
*/
;(async (httpUrl)=> {
// 获取网页数据
let response = await axios.get(httpUrl)
// 获取网页源码
let info = response.data
// 通过正则解析源码获得对象
let result = /heroesJson\((.*?)\)/igs.exec(info)
// 将json 字符串转换为 obj对象
let heroes = JSON.parse(result[1]).heroes
// 循环每个英雄数据
for(let i = 0; i < heroes.length; i++) {
// 分别为对象设置两种下载链接的属性
heroes[i].imgUrl = heroes[i].overlay
heroes[i].iconUrl = heroes[i].icon
// 下载icon文件
await downloadImg('icon', heroes[i])
// 下载img文件
await downloadImg('img', heroes[i])
}
// 提示已下载完
console.log('已全部下载完毕!!!')
})(httpUrl)
- 文件的目录结构
- 爬取结果