写个爬虫呗

1,965 阅读3分钟

之前写了个小爬虫,用来爬当当的图书信息用的,挺好玩,分享一下吧。整个爬虫非常简单,主要是使用request库+cheerio解析,实现非常粗糙,今天正好理一下思路。

首先,准备工作,就是各种库的安装以及其他前置工作的准备,比如页面分析。

整个流程实际上比较简单,适合像我这样的菜鸟观看。

准备工作

npm install request
npm install cheerio
npm install iconv-lite

request是用来请求页面的库,也是本次爬虫最核心的库;cheerio是用于解析的库,将页面转化成DOM来简化数据的解析;iconv-lite是解码库,因为当当网用的不是utf8编码,这点倒是让我吃了不少苦头。

分析清单

下载完需要的库就可以开始撸了,不过撸之前需要先分析页面结构,我列一下分析清单:

  1. 页面结构:分析数据在哪些结构中
  2. 数据形式:图片,文字还是数字
  3. 爬取深度:抓取的数据在当前页面还是需要进入链接(比如商品列表与商品详情,我们需要的数据在详情页,但我们只能通过列表页去爬,这时候深度就是2)
  4. 存储位置:数据保存在哪:文件or数据库
  5. 编码格式:编码不对数据就全是乱码了,这样的数据要了也没用

分析完需要分析的东西就可以接着往下了

初步使用

request({
    encoding:null,
    url:'http://book.dangdang.com/list/newRelease_C01.54.htm'
},function(err,response,body){
    if(err){console.log(err)}
    else{
        //处理数据
        console.log(body)
    }
})

这里解释一下,encoding:null是取消编码,因为默认会按照utf8编码,但页面本身是gb2312的,所以解析了也没用。不写会出问题,因为以gb2312解码的时候数据都被utf8编码过,简直是灾难。

response是服务器端的响应,比如各种头信息啊之类的,这里用不到它。body是页面主体,也就是整个html,是我们需要处理的主角。

但之前也提到了,页面编码是gb2312,因此在解析数据之前先要解码。

var decodeBuffer=iconv.decode(body,"gb2312");//将body以gb2312解析转化成buffer(unicode)
var html=decodeBuffer.toString();
var $=cheerio.load(html);

这时候html是原gb2312解码后又被编码成utf8的字符串,如果打印出来就能发现,里边的中文不再是乱码了。这时候就轮到cheerio登场了:cheerio提供的api和JQuery基本相同,在这里可以直接当成JQuery,因此为了更加靠近JQuery,我们将解析后的数据保存到$这个变量中。

var $=cheerio.load(html);
$(".tushu").each(function(index,ele){
    var bookName=$(ele).find(".name").text();
    console.log(bookName);
})

这时候书名就被打印出来了,是不是很方便。图片我们就用src吧,当然,如果想把图片保存下来也是可以的,用上fs模块就行了

var fs = require("fs");
var path=require("path");
$(".tushu").each(function(index,ele){
    var src=$(ele).find(".cover img").attr("src");
    var srcParse=path.parse(src);
    var srcStore="img/"+srcParse.base;
    request(src).pipe(fs.createWriteStream(srcStore));
})

完整代码

至此,整个爬虫差不多了,因为当当把下一页的链接写在了a标签里,因此同样可以使用选择器这种方式去获取href,以此得知下一页的路径。因此封装一下:

var request=require("request");
var cheerio=require("cheerio");
var iconv=require("iconv-lite");
var path=require("path");
var fs=require("fs");

var main="http://book.dangdang.com";

function spider(url){
    request({
        encoding:null,
        url:url
    },function (err, res, body) {
        var decodeBuffer=iconv.decode(body,"gb2312");
        var result=decodeBuffer.toString();
        var $=cheerio.load(result);
        $('.tushu').each(function(index,ele){
            var src=$(ele).find(".cover img").attr("src");
            var srcpath=path.parse(src);
            var srcStore="img/"+srcpath.base;
            request(src).pipe(fs.createWriteStream(srcStore));
        });
        var next=$('.fanye_bottom > span:nth-child(1) > a:last-child').attr("href");
        var nextUrl=main+next;
        spider(nextUrl);
    })
}

这时候再调用一下spider函数,就可以一页一页往下了。同时我也把详细文章写在了自己博客上,防止下次写的时候忘了怎么用,可以点击访问

小结

当然,这个爬虫很简单,基本上糊弄一下没有任何限制的网站还行。之后要写一个同城租房的毕设项目,准备爬58租房信息。58对ip作了限制,因此访问量太大会出验证码或者封ip,所以需要加上代理等进一步伪装一下。代理的确非常头疼,因为可用率非常低,还记得当初随便找了一个网站,爬了1w多条ip,结果前几个还能用,后面的测试一下基本不可用,最后在筛选的时候就筛选出7-8条,真的心累。后来找到了快代理,可用率还不错,基本能达到12%左右,可以说是非常高的可用率了,毕竟免费。当然有更好的免费代理可以和我说说呀。

第一次写文章,有什么不对的地方欢迎看官指正。