程序员

50行代码抓取一个网站

2018-04-25  本文已影响0人  thisxulz

50行代码抓取一个网站

很多年前写的代码了,只是记录一下

主要使用nodejs + cheerio

cheerio可以采用jquery方式解析dom结构,网上很多不做转述

如果只是json数据的话,可以不用cheerio

实现数据抓取,数据筛选,频率控制,断点续传

npm install cheerio

npm install superagent-prefix

npm install superagent-charset

npm install line-reader

贴代码:

var prefix = require('superagent-prefix')('/static');

var request = require('superagent-charset');

var cheerio = require('cheerio');

var fs = require('fs');

var lineReader = require('line-reader'); //日志定义

var log4js = require('log4js');

log4js.configure("./log4js.json"); //注:配置里的日志目录要先创建,才能加载配置,不然会出异常

var logger = log4js.getLogger('log');

var startUrl = 'http://XXXXXXX.com/search/?q=27age&iy431rzm&per_page=20&wfl=1&page=';//起始地址

var fileName = 'result.txt';//文件生成目录

var num=1;

function doUrl(url){

    request.get(url) .use(prefix) // Prefixes *only* this request

    .charset('utf-8')

    .end(function(err, res){

        if(err){ console.log(err); }

        //获取网页中的json数据

        var json = res.text.substring(res.text.indexOf('app.page["pins"]         =')+19,res.text.indexOf('app.page["page"]')-2);

        var obj = JSON.parse(json);

        var lastId = '';

        if(obj.length > 0){

            for(var i=0;i<obj.length;i++){//数据筛选

                if(obj[i] != null && obj[i].source != null && obj[i].source=='xxxx'){

                    lastId = obj[i].pin_id;

                    appendToFile(fileName, obj[i].pin_id + ',' + obj[i].link + ',http://xxxx.com/pins/' + obj[i].pin_id + ',' + obj[i].repin_count + ',' + obj[i].like_count + ',' + obj[i].comment_count + '\r\n');

                    }

                }

                num++;

                var nextUrl = startUrl + num;//下一页链接

                fs.writeFile('num.txt', num);//记录已经抓取的页号

                logger.info('do next, ulr = ' + nextUrl);//抓取下一页数据

                setTimeout(function(){doUrl(nextUrl)},600);//控制抓取频率,不然很容易被封

            }else {

                logger.info('没有更多数据, url = ' + url);

            }

    });

}

function appendToFile(fileName,line){

    fs.appendFile(fileName,line,function(err){if(err) throw err});

}

lineReader.eachLine('num.txt', function(line, last) {//启动时,从上次抓取的最后一页开始抓取

    num = line;

    doUrl(startUrl + num);//程序启动

    return false;

});

上一篇下一篇

猜你喜欢

热点阅读