• 使用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操作是异步的,且没有锁的概念,如何并发地向同一个文件正确地写入数据

    结果显示如下: 

  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/kevin2chen/p/6815950.html
Copyright © 2020-2023  润新知