nodeJs爬取网页数据

发现node能够爬虫,正好我在找暑期实习,而后就使用node爬一下网站数据找实习。javascript

准备工做

  • 安装node,npm安装依赖包[cheerio, express, eventproxy]
  • httpexpress模块的使用学习

爬取目标网站

//加载http模块
var http = require('http');

//目标网站,嘿嘿,这个网站有不少实习职位
var pageUrl = 'http://shixi.info/';

http.get(pageUrl, function(res) {
    var html = '';
    res.on('data', function(data) {
        html += data;
    });
    res.on('end', function() {
        console.log(html);
    });
});

http的get请求一个目标网站,回调函数的参数是response,绑定两个事件,一个'data'事件,会不断触发获取数据,数据获取完触发’end‘ 事件。html

爬到的的数据就是目标网站的html源代码。java

如今html代码有了,咱们该怎么解析这个呢?node

解析html代码

在这里咱们使用cheerio模块,是服务器端的html解析模块,使用方法类型jQuerygit

var http = require('http');
var cheerio = require('cheerio');
var pageUrl = 'http://shixi.info/';

http.get(pageUrl, function(res) {
    var html = '';
    res.on('data', function(data) {
        html += data;
    });
    res.on('end', function() {
        //数据获取完,执行回调函数
        callback(html);
    });
});

function callback(html) {
    //使用load方法,参数是刚才获取的html源代码数据
    var $ = cheerio.load(html);
    var arrUrl = [];
    
    //写法和jQuery如出一辙,有没有以为很cool
    $('article').each(function(index, element) {
        var href = $(element).find('.entry-title a').attr('href');
        arrUrl.push(href);
    });
}

这样咱们就把目标页面的每条招聘信息的网址存放进了一个数组,固然咱们也能够经过对象字面量存一些其余数据,好比招聘信息的title,date等等。github

可能有人会问,我只要网址干吗?嘿嘿,由于JD是在详情页里面,不去爬详情页,我咋看JD。express

并发请求

为演示方便:只获取了职位title。npm

对arrUrl迭代,GET请求。由于是异步操做,因此在这里咱们建一个count变量,每次完成一个操做count++,执行done函数,若是count值和arrUrl数组的长度相同,执行函数。编程

var count = 0;
var results = [];
function done() {
    if (count == arrUrl.length) {
        console.log('done');
    }
}
arrUrl.forEach(function(item, index) {
    http.get(item, function(res) {
        var html = '';
        res.on('data', function(data) {
            html += data;
        });

        res.on('end', function() {
            var $ = cheerio.load(html);
            var title = $('.entry-title').text();

            results[index] = {
                url: item,
                title: title
            };
            count++;
            done();
        }); 
    });
});

使用express模块让数据响应到网页

var express = require('express');
var app = express();

function done() {
    if (count == arrUrl.length) {
        //get 方法,第一个参数路径,是一个route的做用。
        //回调函数,参数分别是:请求,响应。
        //监听8888端口,浏览器打开 http://127.0.0.1:8888
        app.get('/', function(req, res) {
            res.send(JSON.stringify(results));
        }).listen('8888', '127.0.0.1');
        console.log('done');
    }
}

浏览器打开 http://127.0.0.1:8888,就能看到咱们爬的数据了数组

固然咱们也能够 对这些数据处理一下,返回到网页的是html内容文本。

使用eventproxy模块控制并发

刚才咱们使用的是count变量,有些不够优雅。这里咱们引入eventproxy模块。

var eventproxy = require('eventproxy');
//获得实例化对象ep
var ep = new eventproxy();

//after,第一个参数是事件名,第二个参数是事件的数量,回调函数的参数是list集合,
ep.after('subscribe', arrUrl.length, function(results) {
    app.get('/', function(req, res) {
        res.send(JSON.stringify(results));
    }).listen('8888', '127.0.0.1');
    console.log('done');
});

arrUrl.forEach(function(item, index) {
    http.get(item, function(res) {
        var html = '';
        res.on('data', function(data) {
            html += data;
        });

        res.on('end', function() {
            var $ = cheerio.load(html);
            var title = $('.entry-title').text();
            
            //通知ep的subscribe事件,ep监测执行完的事件数量等于arrUrl.length,若是等于 执行回到函数。
            ep.emit('subscribe', {
                url: item,
                title: title
            });

        }); 
  });

结束

经过nodejs爬虫的学习,学习到了http,express,cheerio,eventproxy的简单使用。更了解到了node异步编程。

《使用 eventproxy 控制并发》

Http模块

相关文章
相关标签/搜索