node.js爬虫爬取拉勾网职位信息

 更新时间:2017年7月6日 23:23  
本篇文章主要介绍了node.js爬虫爬取拉勾网职位信息的方法。具有很好的参考价值。下面跟着小编一起来看下吧 用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招
本篇文章主要介绍了node.js爬虫爬取拉勾网职位信息的方法。具有很好的参考价值。下面跟着小编一起来看下吧

用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招聘信息,共爬取了北京、上海、广州、深圳、杭州、西安、成都7个城市的数据,分别以前端、PHP、java、c++、python、Android、ios作为关键词进行爬取,爬到的数据以json格式储存到本地,为了方便观察,我将数据整理了一下供大家参考

数据结果

上述数据为3月13日22时爬取的数据,可大致反映各个城市对不同语言的需求量。

爬取过程展示

控制并发进行爬取

爬取到的数据文件

json数据文件

爬虫程序

实现思路

请求拉钩网的  “https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false&city=城市&kd=关键词&pn=页数”可以返回一个json格式的数据,该数据包含所要请求职位的信息,省去了使用chreio解析的麻烦,所以直接用superagent来进行请求上述地址,并将数据储存在本地即可,其中参数city是为城市,kd为所要搜索的关键词,pn为要请求的页数,当中使用到了async来控制异步流程,使得并发数不超过3,防止被封ip。

代码地址及使用

github:https://github.com/zsqosos/positionAnalysis

代码请在github上查看,使用该程序需要安装node环境,如果觉得还不错的话烦请给个star,欢迎大家修改使用该程序。

小编给大家推荐的这篇文章详细解析了Android Handler leak分析及解决办法,非常有用,有兴趣的同学可以参考一下

Android Handler leak 分析及解决办法

 In Android, Handler classes should be static or leaks might occur,  Messages enqueued on the application thread's MessageQueue also retain  their target Handler. If the Handler is an inner class, its outer class  will be retained as well. To avoid leaking the outer class, declare the  Handler as a static nested class with a WeakReference to its outer  class.

     在Android中,Handler类应该是静态的,否则,可能发生泄漏。在应用程序线程的MessageQueue中排队的Message对象  还保留他们的目标Handler。如果Handler是一个内部类(注:无论是匿名还是非匿名,匿名是比较常见用法),它的外部类将被保留(至于为什么, 请参考Java嵌套类相关说明)。为了避免泄漏外部类,声明一个Handler子类为静态内部类(注:这样就避免了Handler对象对外部类实例的自动引用),其内部持有一个对外部类对象的WeakReference。

    上面是HandlerLeak的详细解释,同时下划线部分也提供了解决方案的思路。我们需要再分析一下几个泄漏问题:(1)  排队中的Message对象对Handler的持有导致泄漏;(2)Handler对象对外部类(如Activity或Service)实例的强引用持  有。是由于这两个原因同时作用导致出现泄漏的可能。我们的解决方案可以从原因出发,清除这两个原因,就会比较完整的解决这个问题。

    方案:(1)针对第1个原因,在使用Handler的组件生命周期结束前清除掉MessageQueue中的发送给Handler的Message对象(例如在Activity或Service的onDestroy()中调用Handler的remove*方法);(2)针对第2个原因,Handler的实现类采用静态内部类的方式,避免对外部类的强引用,在其内部声明一个WeakReference引用到外部类的实例。

    关于Handler的remove*方法,这儿介绍一下(可以参考源码或文档)

removeCallbacks(Runnable r) ——清除r匹配上的Message。

removeCallbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token为空时,只匹配r。

removeCallbacksAndMessages(Object token) ——清除token匹配上的Message。

removeMessages(int what) ——按what来匹配

removeMessages(int what, Object object) ——按what来匹配

我们更多需要的是清除以该Handler为target的所有Message(包括Callback),那么调用如下方法即可

    handler.removeCallbacksAndMessages(null);

    最终代码像下面这样

 

 代码如下 复制代码

packageorg.dragonboy.example;

  

importjava.lang.ref.WeakReference;

  

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Message;

  

/**

 * @author [email protected]

 */

publicclassMyActivityextendsActivity {

  privateMyHandler mHandler;

  

  @Override

  protectedvoidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

  

    mHandler =newMyHandler(this);

  }

  

  @Override

  protectedvoidonDestroy() {

    // Remove all Runnable and Message.

    mHandler.removeCallbacksAndMessages(null);

  

    super.onDestroy();

  }

  

  staticclassMyHandlerextendsHandler {

    // WeakReference to the outer class's instance.

    privateWeakReference<myactivity> mOuter;

  

    publicMyHandler(MyActivity activity) {

      mOuter =newWeakReference<myactivity>(activity);

    }

  

    @Override

    publicvoidhandleMessage(Message msg) {

      MyActivity outer = mOuter.get();

      if(outer !=null) {

        // Do something with outer as your wish.

      }

    }

  }

}

</myactivity></myactivity>

 

小编推荐的这篇文章介绍了JS实现直接运行html代码的方法,非常实用,有兴趣的同学快来看看吧

1、实例代码:

 

 代码如下 复制代码

<!DOCTYPE html>

<html>

  <head>

    <meta charset='utf-8'/>

    <title>直接运行 html 代码</title>

  </head>

  <body>

    <textarea style='width:300px;height:200px;'id='txtCode'></textarea><br/>

    <input type='button'value='直接运行'id='btnRun'/>

    <script>

      document.getElementById('btnRun').onclick =function(){

        varrunHtml = document.getElementById('txtCode').value;

        if(runHtml){

          varwin = window.open('','运行窗口');

          win.document.open();

          win.document.write(runHtml);

          win.document.close();

        }

        else{

          alert('请输入!');

        }

      }

    </script>

  </body>

</html>

 

2、运行效果图如下:

本文介绍了jsonp跨域请求实现示例,非常有用,不会的同学可以看看

网上看了很多关于jsonp的资料,发现在本机运行后实现不了,有的是有错漏,有的是说的比较含糊,接合自己的情况,整了一个可运行的示例;

前言:

ajax请求地址:http://192.168.1.102:8080/carop/jsonp

服务端要返回的jsonp字符串:jsonpCallback({"name":"刘德华","电话":"17688888888"})

jsonp写法,写法上可以理解成一个javascript函数的执行,例如alert("hello world")会弹出hello  world的窗口,再例如alert({"name":"刘德华"})会弹出[object  Object]的窗口。(注意这里参数两端没加双引号,它是一个有属性的对象而不是一个字符串)

那么本示例的jsonp中,可以将jsonpCallback理解成函数名,{"name":"刘德华","电话":"17688888888"}这个对象是这个函数执行时所要传递的参数。

客户端

 

 代码如下复制代码

$.ajax({

       type:"get",

       async:false,

url:"http://192.168.1.102:8080/carop/jsonp",

       dataType:"jsonp",

jsonpCallback:"jsonpCallback",      

       success:function(data){

       alert(data.name+"\n "+data.tel);

       }

     });

 

其他的ajax方法比如getjson亦可,写法上有区别,这里仅采用一种方法。

说明:jsonpCallback:"jsonpCallback",前一个ajax参数表示要执行的函数,后面的”jsonpCallback“,这个是服务器返回jsonp的javascript函数名。(网上有相关资料这个参数写的是jsonp而不是jsonpCallback,经实际测试要写成jsonpCallback,jquery版本1.8,所测试浏览器为火狐和edge)

服务端

servlet控制器层直接返回jsonp;

 

 代码如下复制代码

importjava.io.IOException;

importjava.io.PrintWriter;

importjavax.servlet.ServletException;

importjavax.servlet.annotation.WebServlet;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

@WebServlet("/jsonp")

publicclassjsonpextendsHttpServlet{

@Override

protectedvoiddoGet(HttpServletRequest req, HttpServletResponse resp)

 throwsServletException, IOException {

 resp.setCharacterEncoding("UTF-8");

 //System.out.println("进入jsonp");

 resp.setContentType("text/json;charset=utf-8");

 String json="{\"name\":\"刘德华\",\"tel\":\"17688888888\"}";

 String jsonp="jsonpCallback("+json+")";

 PrintWriter pw=resp.getWriter();

 System.out.println(jsonp);

 pw.print(jsonp);

}

@Override

 protectedvoiddoPost(HttpServletRequest req, HttpServletResponse resp)

  throwsServletException, IOException {

 // TODO Auto-generated method stub

 doGet(req, resp);

 }

}