使用nodejs爬取拉勾蘇州和上海的.NET職位信息

来源:http://www.cnblogs.com/kklldog/archive/2016/03/11/lagouNodeSpider.html
-Advertisement-
Play Games

最近開始找工作,本人蘇州,面了幾家都沒有結果很是傷心。在拉勾上按照城市蘇州關鍵字.NET來搜索一共才80來個職位,再用薪水一過濾,基本上沒幾個能投了。再加上最近蘇州的房價蹭蹭的長,房貸壓力也是非常大,所以有點想往上海去發展。閑來無聊寫了個小爬蟲,爬了下蘇州跟上海的.NET職位的信息,然後簡單對比了一


最近開始找工作,本人蘇州,面了幾家都沒有結果很是傷心。在拉勾上按照城市蘇州關鍵字.NET來搜索一共才80來個職位,再用薪水一過濾,基本上沒幾個能投了。再加上最近蘇州的房價蹭蹭的長,房貸壓力也是非常大,所以有點想往上海去發展。閑來無聊寫了個小爬蟲,爬了下蘇州跟上海的.NET職位的信息,然後簡單對比了一下。

是的小弟擅長.NET,為啥用nodejs?因為前幾天有家公司給了個機會可以轉nodejs,所以我是用來練手的,不過後來也泡湯了,但是還是花兩晚寫完了。剛學,代碼醜輕噴哈!

一:如何爬取拉勾的數據

這個其實非常簡單,本來還以為要用正則去分析html,其實拉勾分頁提了ajax的介面,可以直接用http去訪問。打開神器Chrome的F12一看便知。

這是用nodejs模擬分頁請求的代碼:

var getData = function (kd,city,pn) {
    var mongo = require('./mongo');
    var http = require('http');
    var queryString = require('querystring');

    var postData=queryString.stringify({
        'pn':pn,
        'kd':kd,
        'first':false
    });

    var options = {
        hostname:'www.lagou.com',
        method:'POST',
        path:'/jobs/positionAjax.json?px=default&city='+city,
        headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': postData.length
        }
    };
    
    var postResult = '';
    
    var req = http.request(options,(res)=>{
        console.log(`STATUS:${res.statusCode}`);
        res.setEncoding('utf8');
        res.on('data',(chunk)=>{
            postResult+=chunk;
        }); 
        res.on('end',()=>{
            console.log(`RESULT:${postResult}`);
            var jsonObj =JSON.parse(postResult);
            //insert into db
            jsonObj.content.result.forEach((item)=>{
                var salary = item.salary;
                //拆分3k-6k,易於統計
                var arr = salary.split('-');
                var min = arr[0].substring(0,arr[0].indexOf('k'));
                var max = arr.length>1? arr[1].substring(0,arr[1].indexOf('k')):min;
                item.salaryMin = parseInt(min);
                item.salaryMax = parseInt(max);
                
                mongo.save(city,item);
            });
            if(jsonObj.content.hasNextPage&&jsonObj.content.totalPageCount>pn){
                getData(kd,city,pn+1);
            }
        });
        req.on('error',(e)=>{
            console.log(`problem with request:${e.message}`);
        }); 
    });

    req.write(postData);
    req.end();
    console.log(`start to get data. pn:${pn} city:${city} kd:${kd}`);
};

exports.run = getData;

二:數據存儲在哪裡

拉勾的分頁介面返回的是json對象,那麼自然是存mongoDb最簡單了。

下麵是mongoDb的封裝:

var save=function (city,jsonObj) {
    var Db = require('mongodb').Db;
    var Server = require('mongodb').Server;

    var db = new Db('test',new Server('localhost',27017))

    db.open((err,db)=>{
        var coll = db.collection(city);
        coll.save(jsonObj,(err,r)=>{
            if(!err){
               console.log('save to '+city); 
            }
            
            db.close();
        });
        
    });
};

var removeAll = function (city,callback) {
    var Db = require('mongodb').Db;
    var Server = require('mongodb').Server;

    var db = new Db('test',new Server('localhost',27017))

    db.open((err,db)=>{
        var coll = db.collection(city);
        coll.remove((err,numOfRows)=>{
            if(!err){
                console.log(`${city} collection be removed. ${numOfRows}`);
            }
            db.close();
            callback(err);
        });
      
    });
};

var readAll=function (city,callback) {
    var Db = require('mongodb').Db;
    var Server = require('mongodb').Server;

    var db = new Db('test',new Server('localhost',27017))

    db.open((err,db)=>{
        var coll = db.collection(city);
        var cursor = coll.find();
        cursor.toArray((err,results)=>{
            if(!err){
                callback(results);
                //db.close();        
            }
            db.close();
        });
    });
}

exports.save = save;
exports.removeAll = removeAll;
exports.readAll = readAll;
 

三:如何展示數據

使用nodejs自帶的httpServer,接受到請求的時候直接讀取一個html文件,然後把對比的信息填入html文本里,用一個h5的chart來展示

下麵是伺服器的代碼:

var http = require('http');
var fs = require('fs');
var stati = require('./statistics');
var szStati = {text:'SuZhou'};
var shStati = {text:'ShangHai'};

var server=new http.Server();  
server.on('request',function(req,res){  
    res.writeHead(200,{'Content-Type':'text/html'});  
    
    fs.readFile('./index.html','utf8',(err,data)=>{
        if (err) {
            throw err;
        }
        console.log(data);
        // res.write(data);
        // res.end();
        stati.statiSalary('蘇州',(results)=>{
            szStati.values = results;
            stati.statiSalary('上海',(results)=>{
                shStati.values = results;
                var series =[szStati,shStati];
                var strSeries = JSON.stringify(series);
                console.log(strSeries);
                
                data = data.replace('@series',strSeries);
                console.log(data);
                
                res.write(data);
                res.end();
            });
        });
    });
});  
  
server.listen(3000);  
console.log('http server started...port:3000');

四:統計結果

統計按照 0-5k,5-10k,10-15k,15-20k,20-25k,>25k這幾個區間按照職位的數量進行統計。

0-5k:上海是蘇州的4倍

5-10k:上海是蘇州的4倍

10-15k:上海是蘇州的9倍

15-20k:上海是蘇州的12倍

20-25k:上海是蘇州的17倍

>25k:上海是蘇州的26倍

可以看到從10-15k開始的職位,上海的數量是蘇州的10多倍,越是高薪的職位倍數越高。由此可以看出,蘇州跟上海的差距還是非常大的。蘇州政府一直沾沾自喜,覺得自己在互聯網圈子有多牛逼,搞了一堆孵化器,但其實拿的出手的公司有幾家呢,一隻手都數過來了,跟北上廣深一線還是差的很遠呢,還是要努力啊。

恐怕我也要背井離鄉去上海的尋找未來了。

還沒學會用VS Code上傳到github上,先直接上傳代碼吧:lagouSpider.zip


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分散式dubbo zookeeperfastdfsactivemqredis 分散式緩存
  • 1 package com.shejimoshi.behavioral.TemplateMethod; 2 3 4 /** 5 * 功能:抽象模板類 6 * 時間:2016年3月10日下午9:02:32 7 * 作者:cutter_point 8 */ 9 public abstract class
  • 本節目錄 介紹 定義Filter 設置Filter 這是Abp中多租戶、軟刪除、激活\禁用等如此方便的原因 Install-Package EntityFramework.DynamicFilters 定義數據 class DemoDb : DbContext { public DemoDb() :
  • 在做h5移動頁面,相信大家一定碰到過頁面已經打開,但是裡面的圖片還未載入出來的情況,這種問題雖然不影響頁面的功能,但是對於不利於用戶體驗。拋開網速的原因,解決這個問題有多方面的思路:最基本的,要從http請求合併,緩存管理,圖片壓縮等方面做性能優化;另外就是可以對頁面里用到的所有圖片做預載入的處理。
  • 數組的5個迭代方法: every(); //對數組中的每一項運行給定函數,如果該函數對每一項都返回true,則返回true; filter(); //對數組中的每一項運行給定函數,返回該函數會返回true的項組成的數組; forEach(); //對數組中的每一項運行給定函數,這個方法沒有返回值;
  • 閑來無聊,收集總結一下jQuery常用操作,希望對新手有用。 基於jquery 1.3.2 <!--<script type="text/javascript" src="jquery/jquery-1.3.2.js"></script>--><!--<script src="https://aja
  • web語義化是什麼 HTML5標準出來的時候,我曾經詫異為什麼要定義這麼多header footer nav article標準,DIV不挻好的嘛,方便開發人員記憶啊。但當頁面開發完,面對所有都是DIV標簽的網頁,就會混亂了,到底哪裡是頁頭,哪裡是正文。當然我們可以用瀏覽器打開,F12一下,就一目了
  • 寫Web頁面就像我們建設房子一樣,地基牢固,房子才不會倒。同樣的,我們製作Web頁面也一樣,一個良好的HTML結構是製作一個美麗的網站的開始,同樣的,良好的CSS只存在同樣良好的HTML中,所以一個乾凈的,語義的HTML的優點很多,那麼平時製作中,我們做到了這一點嗎?我們一起來看一張圖片: 上圖展示
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...