zoukankan      html  css  js  c++  java
  • 使用nodejs爬前程无忧前端技能排行(半半成品)

    最近准备换工作,需要更新一下技能树。为做到有的放矢,想对招聘方的要求做个统计。正好之前了解过nodejs,所以做了个爬虫搜索数据。

    具体步骤:

    1.  先用fiddler分析请求需要的header和body。

    2.  再用superagent构建上述数据发送客户端请求。

    3.  最后对返回的数据使用cheerio整理。

    折腾了几个晚上,只搞出了个架子,剩余工作等有时间再继续开发。

    /*使用fiddler抓包,需要配置lan代理,且设置如下参数*/
    process.env.https_proxy = "http://127.0.0.1:8888";
    process.env.http_proxy = "http://127.0.0.1:8888";
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    
    /*使用到的模块*/
    var request = require('superagent');    //发送客户端请求
    require('superagent-proxy')(request);   //使用代理发送请求
    var cheerio = require('cheerio');       //以jq类似的方法操作返回的字符,不需要用正则
    require('superagent-charset')(request);//node不支持gbk,gb2312,this will add request.Request.prototype.charset.
    var async = require('async');           //异步流控制模块
    var fs = require('fs');
    
    /*相关参数,通过fiddler抓包后复制过来*/
    var ws = fs.createWriteStream('res.html',{flags:'w+'}); //a+追加的读写模式,w+覆盖
    var loginUrl = "https://login.51job.com/login.php";
    var searchUrl = "http://search.51job.com/jobsearch/search_result.php";
    var queryStrings = "fromJs=1&jobarea=020000&keyword=%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91&keywordtype=2&lang=c&stype=2&postchannel=0000&fromType=1&confirmdate=9";
    var loginForms = {
        lang: 'c',
        action: 'save',
        from_domain: 'i',
        loginname: '***',   //自己的用户名和密码
        password: '***',
        verifycode: '',
        isread: 'on'
    };
    var searchForms = {
        lang: 'c',
        stype: '2',
        postchannel: '0000',
        fromType: '1',
        line: '',
        confirmdate: '9',
        from: '',
        keywordtype: '2',
        keyword: '%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91',
        jobarea: '020000',
        industrytype: '',
        funtype: ''
    };
    var searchFormsString='lang=c&stype=2&postchannel=0000&fromType=1&line=&confirmdate=9&from=&keywordtype=2&keyword=%C7%B0%B6%CB%BF%AA%B7%A2&jobarea=020000&industrytype=&funtype=';
    var proxy0 = process.env.https_proxy;
    var proxy = process.env.http_proxy;
    
    const agent = request.agent();          //agent()方法产生的实例会保存cookie供后续使用
    request.post(loginUrl).proxy(proxy0).send(loginForms).end(function (err,res0) {
        agent.post(searchUrl)
            .proxy(proxy)                   //proxy()方法需紧跟在method方法之后调用,否则fiddler抓不到数据包
            .type('application/x-www-form-urlencoded')
            .query(queryStrings)        //使用字符串格式
            .send(searchFormsString)
            .charset('gbk')                //通过charset可知编码字符格式,不设置会有乱码
            .end(function (err, res) {
                /* 以下是处理返回数据的逻辑代码*/
                var $ = cheerio.load(res.text);   //res.text是返回的报文主体
                async.each($('.el.title').nextAll('.el'), function(v, callback) {
                    //将多余的内容删除,保留岗位、公司链接
                    $(v).prepend($(v).find('.t1 a'));
                    $(v).find('.t1').remove();
                    ws.write($.html(v), 'utf8');
                }, function(err) {
                    console.log(err);
                });
                console.log('successful');
            })
    });
    
    //jquery内置document元素为root,cheerio需要通过load方法传入,然后用选择器查找指定元素,再执行相应操作。
    // $.html(el);静态方法,返回el元素的outerHtml
    //TODO
    // 1.当前只请求到一页数据,还需构建所有页数的请求列表
    // 2.向每条数据的岗位链接发送请求,获取技能关键字,存入文件中
    // 3.node中io操作是异步的,且没有锁的概念,如何并发地向同一个文件正确地写入数据

    结果显示如下: 

  • 相关阅读:
    iOS身份证号码识别
    GPS定位开发
    Xcode8注释有时会失效的解决方法
    本地缓存FMDB的使用(iOS)
    iOS蓝牙开发
    极光推送
    查找当前数据库服务器中某张表存在于哪个数据库中
    redis安装配置记录
    python 之生成器
    python之迭代
  • 原文地址:https://www.cnblogs.com/kevin2chen/p/6815950.html
Copyright © 2011-2022 走看看