这两天刚换了linux系统,一直感觉自带的桌面图片有限而且不是特别“性感”,决定去弄几张图片回来当桌面壁纸,搜索了一下壁纸站点,觉得zol的还不错,分类清晰,壁纸质量上乘,就决定下载几张,但是网站繁琐的导流量页面导致下载一个图片非常繁琐和缓慢,而且效率太低下了,作为码农怎么能忍,分析一下,给他来个一锅端,12万的壁纸,尽收硬盘中。好了,上边的就是需求的描述了,下边是干货抓取过程。

1. 开发环境Nodejs。环境搭建就不累述了,知道的去nodejs官网自己简单科普一下就好了。传送到nodejs官网

2. 手把手过程

2.1 初始化工程

  

#新建个项目目录
mkdir zol_desk
#进入项目目录
cd zol_desk
#初始化npm
npm init
#一路回车知道完成
#安装crawler工具
npm install crawler --save
#安装个lodash工具,有可能会用到,处理数据方便一些。
npm install lodash --save
#创建个list.js文件,用来抓取列表数据
touch list.js

2.2 list.js 内容

 1 const fs = require('fs');
 2 const Crawler = require('crawler');
 3 const _ = require('lodash'); //就用到一个range函数,其实用for循环也可以,只是用习惯了而已
 4 //桌面站点的路由模式http://desk.zol.com.cn/pc/x.html, 这里的x代表页数,如1,2,3,...2000
 5 const PATH_URL = 'http://desk.zol.com.cn/pc/x.html';
 6 const L = 334; //334是最大页数,实际网站分析得到的这个数
 7
 8 let cnt = 0;
 9
10 let RS = [];
11
12 var c = new Crawler({
13     maxConnections : 10,
14     callback : function (error, res, done) {
15         if(error) {
16             console.log(error)
17         } else {
18             var $ = res.$;
19             var list = $('.pic-list2 li a');
20             list.each((k, item)=>{
21                 RS.push(item.attribs.href);
22             });
23             console.log(`${cnt++} / ${L}`); //这里就是为了自己在console中看到进展,没有实际用处。
24         }
25         done();
26     }
27 });
28
29 const makeList = ()=> {
30     return _.range(1, L + 1).map(item=>PATH_URL.replace('x', item));
31 }
32
33 const writeListJson = ()=>{
    //写入列表文件
34 fs.writeFile('./data/list.json', JSON.stringify(RS), function(){ 35 console.log('all requests done and json saved!') 36 }); 37 } 38 39 c.queue(makeList()); 40 41 c.on('drain', writeListJson);

2.3 pics.js 图片详情页面,因为是每一个合集,里面还有更多的具体图片路径,将其中图片路径整理出来。

 1 const fs = require('fs');
 2 const Crawler = require('crawler');
 3 const _ = require('lodash');
 4 let data = require('./data/list.json');
 5 const DOMAIN = 'http://desk.zol.com.cn';
 6
 7 let cnt = 0;
 8 let RS = [];
 9
10 const makeList = ()=> {
11     return data.map(item=> DOMAIN + item);
12 }
13
14 data = makeList();
15
16 var c = new Crawler({
17     maxConnections : 10,
18     callback : function (error, res, done) {
19         if(error) {
20             console.log(error)
21         } else {
22             var s = res.body.match(/var deskPicArr .+;/)[0];
23             s = s.replace(/var\sdeskPicArr\s+=\s+/, '');
24             s = s.replace(/;\s{0,}$/g, '');
25             var x = JSON.parse(s).list;
26             x = x.map(item=>{
27                 return item.imgsrc.replace('##SIZE##', item.oriSize)
28             });
29             RS = [...RS, ...x];
30             console.log(cnt++ + '/' + data.length )
31         }
32         done();
33     }
34 });
35
36
37 c.queue(data);
38
39 c.on('drain', function(){
40     fs.writeFile('data/pics.json', JSON.stringify(RS), function(err, data){
41         if(err) console.log(err);
42         console.log('fileSaved!')
43     })
44 });

2.4 images.js 根据整理出来的图片路径,下载相应的图片到本地磁盘路径下。

 1 const fs = require('fs');
 2 const chalk = require('chalk');
 3 const Crawler = require('crawler');
 4 const _ = require('lodash');
 5 let data = require('./data/pics.json');
 6 let cnt = 0;
 7 const DOMAIN = 'http://desk.zol.com.cn';
 8 const parseFileNameFromUrl = (url)=> {
 9     var a = url.split('/');
10     return a[a.length -1];
11 }
12
13
14 var c = new Crawler({
15     encoding: null,
16     jQuery: false,
17     maxConnections : 10,
18     callback: function (error, res, done) {
19         if(error) {
20             console.log(error)
21         } else {
22             const fileName = parseFileNameFromUrl(res.options.uri);
23             const str = chalk.blue('fileName = ' + fileName)
24             console.log(str);
25             fs.createWriteStream('./data/images/' + fileName).write(res.body);
26             console.log(cnt++ + '/' + data.length )
27         }
28         done();
29     }
30 });
31
32
33 c.queue(data);
34
35 c.on('drain', function(){
36     console.log('All images saved!')
37 });
01-06 14:20
查看更多