美文网首页
爬虫帮我找工作

爬虫帮我找工作

作者: 不要葱谢谢 | 来源:发表于2017-03-22 21:43 被阅读0次

最近在找前端的工作,无奈对大杭州的各大区不是很熟悉,每次看到公司的地址都要点进地图里看看具体位置。于是生出一个想法,能不能把招聘的信息标注在地图上,这样看起来就很直观了。
花了一天时间,撸了一个简单的版本,发出来分享一下,也为自己作一个小结。
附上GitHub地址,欢迎交流指正~

分析

我的习惯是在写代码之前先分析一下自己的需求和要达到的效果,以便于选择合适的技术和工具。

分析过程:

  1. 我的首要需求是招聘的信息,这部分信息要通过爬虫去抓取。因为之前写过Node.js的爬虫,所以选择Node.js来编写爬虫。
  2. 发送请求可以使用Node.js自带的https模块,也可以使用其他第三方的模块。我选择了superagent模块,用起来比较方便。(这里提一句,因为我爬的是拉勾,人家用的是https协议,所以要用https模块去发送请求)
  3. 考虑到爬取的链接会比较多,一口气发送那么多请求秒秒钟就被人家封IP了,所以要控制一下并发数,这里我选择了async模块。
  4. 爬到的数据用cheerio模块处理,如果有编码问题,可以用iconv-lite转换一下编码。拉勾用的是utf-8,就省去了这一步。
  5. 拿到所有数据之后,要把数据显示在地图上,毫无疑问要用到地图,这里选择用百度地图API。
  6. 考虑到易用性,加一个opn模块,自动打开浏览器,进入网页。

实现

编写爬虫之前先分析一下url,打开前端开发的页面,发现它的url是这样的:
https://www.lagou.com/zhaopin/qianduankaifa/?filterOption=3
再打开第二页,是这样:
https://www.lagou.com/zhaopin/qianduankaifa/2/?filterOption=3
于是我们找到了一个规律,每一页的url可以通过函数来生成

function url(pageNum){
  return `https://www.lagou.com/zhaopin/qianduankaifa/${pageNum}/?filterOption=3`;
}

假设我们随便爬一个

const superagent = require('superagent');
const cheerio = require('cheerio');
let _url = url(1);

superagent
  .get(_url)
  .end((err,res)=>{
    if(err) console.log(err);
    let $ = cheerio.load(res);
    //...
    //这里用cheerio处理res,拿到我们要的链接,用法参照jQuery
  });

响应回来的res是整个页面的html,把它交给cherrio进行处理。

OK,然后回到浏览器来看一下,一个页面中一共列了15条招聘信息,我们要拿到它们的链接好进入招聘详情页抓取需要的数据。于是,F12打开调试工具,找到对应a标签的位置


sp20170322_160532.png

这里可以看到,a标签中的href属性的值就是我们需要的链接,目标明确了,接下来用cheerio处理,就像用jQuery那样,简单粗暴

let hrefs = [];
$('a.position_link').each(function () {
  hrefs.push($(this).attr('href'));
});
unique(hrefs);  //简单的去个重,防止有重复的链接出现

考虑到反爬虫的机制,我们可以设置一下请求头来模仿浏览器请求,比如我们设置一个"User-Agent"字段

superagent
  .get(_url)
  .set({'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'})
  .end((err,res)=>{
    if(err) console.log(err);
  });

除了通过模仿浏览器请求来绕过反爬虫策略,还应该控制一下并发,这里用async模块

const async = require('async');
let limit = 5;
async.mapLimit(urls,limit,(url,callback)=>{
  //code...
  callback(null,data); //每次并发操作的结果data通过callback传递给results
},(err,results)=>{
  if(err) console.log(err);
  console.log(results);  //results是一个数组,包含了每个并发任务中传过来的data
});

每个并发任务完成后,处理完的data通过调用callback函数传递到最终的结果数组results中。上述代码,等所有并发任务完成后,会执行回调函数,打印出结果数组。

如此一来,我们就可以拿到包含详情页url的数组,然后通过这些url再去抓取具体的职位信息。待所有需要的信息都抓取到后,我们就可以拼装数据,把数据挂载到路由下了。

数据有了,剩下的就是把数据显示在百度地图上了,使用方法参见百度地图API

使用百度地图API v1.5以后的版本(最新版v2.0)前要先申请一个密钥(ak),然后在index.html中引入

<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的密钥"></script>

ps: 抓取到的地址信息是文字形式的地址,而百度地图API使用的是经纬度坐标,所以要将地址转换成经纬度。百度地图中提供了Geocoder类,可以生成一个地址解析器,将地址信息解析成经纬度坐标。

API文档

小结

虽然只是一个并不复杂的项目,但还是暴露出了一些问题,比如模块的划分,感觉还不够合理,代码的规划也略显凌乱。之后还会对代码进行修改,努力写出更加优雅的代码。

相关文章

网友评论

      本文标题:爬虫帮我找工作

      本文链接:https://www.haomeiwen.com/subject/crxnnttx.html