如何获取拉勾的职位数据进行统计!

数据展示地址:http://lg.otpath.com/

项目代码地址:https://github.com/WayneLiang/crawler-lagou

爬虫开始

环境要求

  • Node.js环境
  • Mongodb环境

主要模块

  • superagent 网络请求
  • superagent-proxy 代理IP转发
  • cheerio jQuery 核心实现
  • mongoose mongodb数据库使用
  • koa web框架
  • echarts 数据统计图表

一、抓取代理IP

防止请求过于频繁导致ip被网站屏蔽,请求都是使用代理IP进行。所以必须先获取对可用的代理IP,我选择http://www.xicidaili.com/nn/ 上的代理。然而获取回来的IP并不是每一个都可用,故需使用代理去请求http://ip.chinaz.com/getip.aspx ,若3秒内有响应即当作可用。具体代码如下:

var Models = require('../lib/core');
var $Ip = Models.$Ip;
var request = require('superagent');
var cheerio = require('cheerio');
require('superagent-proxy')(request);
(async function () {  
  for(var page = 1; page <= 10; page++){    
    //请求代理IP页面
    var res = await request.get('http://www.xicidaili.com/nn/' + page);    
    var $ = cheerio.load(res.text);    
    var tr = $('tr');    
    //从第二行开始获取IP和端口
    for(var line = 1 ; line < tr.length ; line++ ){      
      var td = $(tr[line]).children('td');      
      var proxy =  'http://' + td[1].children[0].data + ':' + td[2].children[0].data;     
      try {        
        //代理IP请求,设置超时为3000ms,返回正确即当可用
        var testip = await request.get('http://ip.chinaz.com/getip.aspx').proxy(proxy).timeout(3000);  
        if(testip.statusCode == 200 && testip.text.substring(0,4) == '{ip:' ){  
          //存入数据库
          await $Ip.addIp({proxy: proxy});        
        }
      }catch (error){      
      }    
    }  
  }
})();

二、抓取拉勾数据

  • 1.抓取城市列表
    直接使用superagent请求http://www.lagou.com/lbs/getAllCitySearchLabels.json 即可获取城市列表

  • 2.抓取职位列表

    • superagent请求http://www.lagou.com
    • cheerio加载返回的html
    • 获取id=sidebar的所有数据(menu_main类是一级,menu_sub类是二级)
async function crawlerPosition() {  
  var res = await request.get('http://www.lagou.com');  
  var $ = cheerio.load(res.text);  
  var length = $('#sidebar .menu_box').length;  
  var positions,position = {};  
  for(var num=0 ; num < length; num++){    
    position.name = $($('.menu_main h2')[num]).text().replace(/\n/g,'').replace(/ /g,'');    
    position.sub = [];    
    var menu_sub = ($($('.menu_sub')[num]).children('dl'));    
    for(var subnum=0 ; subnum < menu_sub.length; subnum++){      
      var subPosition = {};      
      subPosition.name = $(menu_sub[subnum]).children('dt').children('a').text();      
      subPosition.position = [];      
      positions = $(menu_sub[subnum]).children('dd').children('a');      
      for(var positionnum=0 ; positionnum < positions.length; positionnum++){       
        subPosition.position.push($(positions[positionnum]).text());      
      }      
      position.sub.push(subPosition);    
    }    
    await $Position.addPosition(position);  
  }  
  console.log('**************finish crawer position data***************');
}
  • 3.抓取各职位在各城市的招聘总数
    使用superagent和superagent-proxy代理请求http://www.crawler.com/jobs/positionAjax.json?px=new&city= 请求如果出错或无法获取数据则切换下一个IP再请求一遍,请求是需要post的表单为{ kd: position.name, pn: page }
async function crawlerJobTotal(city,position) {  
  var proxy = ips[ipNo++].proxy;  
  var positionResult,jobResult;  
  if(ipNo >= ips.length){    ipNo = 0;  }  
  try {    
    positionResult = await request.post('http://www.crawler.com/jobs/positionAjax.json?px=new&needAddtionalResult=false&city='+city) 
                                  .type('application/x-www-form-urlencoded')        
                                  .send({ kd: position.name, pn: 1,first:true })
                                  .proxy(proxy)
                                  .timeout(3000);  
  }catch(error){   
    console.log('request error, again');    
    return await crawlerJobTotal(city,position);  
  }  
  var totalCount;  
  if(positionResult.body && positionResult.body.success && (positionResult.body.content.length != 0)  &&(positionResult.body.content.positionResult!= 0)){    
    totalCount = positionResult.body.content.positionResult.totalCount;
    console.log(city,position.name,1,Date.now(),totalCount);    
    var item = {};    
    item.city = city;    
    item.position = position.name; 
    item.firstTag = position.firstTag;    
    item.secondTag = position.secondTag;    
    item.total = totalCount;    
    await $JobTotal.addJobTotal(item);  
  }else{    
    console.log('could not get positionResult,again',proxy);
    return await crawlerJobTotal(city,position);  
  }
}
  • 4.抓取各职位在各城市的具体招聘情况
    使用superagent和superagent-proxy代理请求http://www.crawler.com/jobs/positionAjax.json?px=new&city= 请求如果出错或无法获取数据则切换下一个IP再请求一遍,请求是需要post的表单为{ kd: position.name, pn: page },这里需要注意的是拉勾返回的总的数据数会比json数据里面的totalCount少。这部分代码请看https://github.com/WayneLiang/crawler-lagou/blob/master/crawler/lagou.js#L22

三、数据展示

  • 具体数据展示可以访问http://lg.otpath.com/
  • 具体实现代码可以看https://github.com/WayneLiang/crawler-lagou
  • 具体echarts图表的使用可以访问http://echarts.baidu.com/
如何获取拉勾的职位数据进行统计!_第1张图片
地区分布.png
如何获取拉勾的职位数据进行统计!_第2张图片
薪资分布.png
如何获取拉勾的职位数据进行统计!_第3张图片
工作经验与薪资.png

你可能感兴趣的:(如何获取拉勾的职位数据进行统计!)