Node实战-----爬取网页图片

      在本篇博文中我将实现一个完整的实例:主要使用Node.js爬取一个网页,须要经过第三方模块cheerio.js分析这个网页的内容,最后将这个网页的图片保存个在本地。node

1、项目目录与思路

      新建一个项目名为:project_01,输入命令在控制台,使其生成package.json文件:git

命令:github

npm init

 

在控制台输入npm install命令下载须要的模块,在本项目中须要的request和cheerio模块,将使用命令进行下载到本地:npm

命令:json

npm install request cheerio -S

 

 

此时项目的文件夹的目录为:dom

 

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

打开node_modules文件夹能够看到相应的模块:函数

 

 

 

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

   2、   配置网页地址及图片存放的文件夹

配置内容:config.js中,在文件中经过exports导出这些配置内容,从而使其它文件可使用ui

以爬码农网为例this

代码:

config.js

 

const url='http://www.codeceo.com/';//填写本身请求的具体的网址

const path=require('path'); const imgDir=path.join(__dirname,'img'); module.exports.url=url; module.exports.imgDir=imgDir;

 

3、解析DOM获得的图片地址

        获得DOM结构以后,将分析DOM部分代码写入analyze.js文件中,经过cheerio获得每一张图片的地址,最后利用一个回调函数callback处理这个地址(这里的回调函数callback是发送请求):

代码:

analyze.js:

const cheerio=require('cheerio'); const fs=require('fs'); function findImg(dom,Callback){ let $=cheerio.load(dom); $('img').each(function(i,elem){ let imgSrc=$(this).attr('src'); Callback(imgSrc,i); }); } module.exports.findImg=findImg;

  cheerio模块能够像jQuery同样操做DOM,这里获得的是请求网页中每一张图片的文件地址

       

 

4、请求图片的地址以及图片文件的保存

请求图片的的地址:

     将请求的操做放在主模块index.js文件中,将config.js和analyze.js文件引入这个模块,利用request模块请求图片的地址,获得DOM结构,将DOM结构给analyze的findImg方法处理,代码:

 

const http=require('http'); const fs=require('fs'); const request=require('request'); const path=require('path'); const config=require('./config'); const analyze=require('./analyze'); function start(){ request(config.url,function(err,res,body){ console.log('start'); if(!err && res){ console.log('start'); analyze.findImg(body); } }) }

 

图片文件的保存:

   经过分析DOM结构获得图片地址后,利用request再次发送请求,将请求获得的数据写入本地便可,这里也将其封装为一个函数,追加在index.js文件中:

代码:

function downLoad(imgUrl,i){ let ext=imgUrl.split('.').pop(); request(imgUrl).pipe(fs.createWriteStream(path.join(config.imgDir,i+'.'+ext),{ 'enconding':'binary' })) console.log(i); }

注意:所获取的数据的二进制数据,因此必定要设置编码格式为binary,由于writeFile的默认编码格式为utf-8,不然保存的图片没法打开。

      同时,咱们须要将这个download函数做为参数传递给analyze模块的findImg方法,最后运行这个项目的主函数start(),这样项目才会运行起来

index.js

const http=require('http'); const fs=require('fs'); const request=require('request'); const path=require('path'); const config=require('./config'); const analyze=require('./analyze'); function start(){ request(config.url,function(err,res,body){ console.log('start'); if(!err && res){ console.log('start'); analyze.findImg(body,downLoad); } }) } function downLoad(imgUrl,i){ let ext=imgUrl.split('.').pop(); request(imgUrl).pipe(fs.createWriteStream(path.join(config.imgDir,i+'.'+ext),{ 'enconding':'binary' })) console.log(i); } start();

 

 

最终的结果显示:

 

 运行代码不到5秒钟,就抓取完了并命名好了,这相对于咱们手动保存,速度很是快

 你想抓取哪一个网站的图片就抓取哪一个网站的图片(固然除了那些作了防爬虫处理的)。

项目源代码:https://github.com/life2022/SSH_Forum/tree/master/project_01

相关文章
相关标签/搜索