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

爬虫帮我找工作

作者: 不要葱谢谢 | 来源:发表于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