国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

node爬取拉勾網數據并導出為excel文件

來源:懂視網 責編:小采 時間:2020-11-27 19:34:07
文檔

node爬取拉勾網數據并導出為excel文件

node爬取拉勾網數據并導出為excel文件:這篇文章主要介紹了關于node爬取拉勾網數據并導出為excel文件,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下前言之前斷斷續續學習了node.js,今天就拿拉勾網練練手,順便通過數據了解了解最近的招聘行情哈!node方面算是萌新一個吧,希望可
推薦度:
導讀node爬取拉勾網數據并導出為excel文件:這篇文章主要介紹了關于node爬取拉勾網數據并導出為excel文件,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下前言之前斷斷續續學習了node.js,今天就拿拉勾網練練手,順便通過數據了解了解最近的招聘行情哈!node方面算是萌新一個吧,希望可

一、概要

我們首先需要明確具體的需求:

  1. 可以通過node index 城市 職位來爬取相關信息

  2. 也可以輸入node index start直接爬取我們預定義好的城市和職位數組,循環爬取不同城市的不同職位信息

  3. 將最終爬取的結果存儲在本地的./data目錄下

  4. 生成對應的excel文件,并存儲到本地

二、爬蟲用到的相關模塊

  • fs: 用于對系統文件及目錄進行讀寫操作

  • async:流程控制

  • superagent:客戶端請求代理模塊

  • node-xlsx:將一定格式的文件導出為excel

  • 三、爬蟲主要步驟:

    初始化項目

    新建項目目錄

    在合適的磁盤目錄下創建項目目錄 node-crwl-lagou

    初始化項目

    1. 進入node-crwl-lagou文件夾下

    2. 執行npm init,初始化package.json文件

    安裝依賴包

    1. npm install async

    2. npm install superagent

    3. npm install node-xlsx

    命令行輸入的處理

    對于在命令行輸入的內容,可以用process.argv來獲取,他會返回個數組,數組的每一項就是用戶輸入的內容。
    區分node index 地域 職位node index start兩種輸入,最簡單的就是判斷process.argv的長度,長度為四的話,就直接調用爬蟲主程序爬取數據,長度為三的話,我們就需要通過預定義的城市和職位數組來拼湊url了,然后利用async.mapSeries循環調用主程序。關于命令分析的主頁代碼如下:

    if (process.argv.length === 4) {
     let args = process.argv
     console.log('準備開始請求' + args[2] + '的' + args[3] + '職位數據');
     requsetCrwl.controlRequest(args[2], args[3])
    } else if (process.argv.length === 3 && process.argv[2] === 'start') {
     let arr = []
     for (let i = 0; i < defaultArgv.city.length; i++) {
     for (let j = 0; j < defaultArgv.position.length; j++) {
     let obj = {}
     obj.city = defaultArgv.city[i]
     obj.position = defaultArgv.position[j]
     arr.push(obj)
     }
     }
     async.mapSeries(arr, function (item, callback) {
     console.log('準備開始請求' + item.city + '的' + item.position + '職位數據');
     requsetCrwl.controlRequest(item.city, item.position, callback)
     }, function (err) {
     if (err) throw err
     })
    } else {
     console.log('請正確輸入要爬取的城市和職位,正確格式為:"node index 城市 關鍵詞" 或 "node index start" 例如:"node index 北京 php" 或"node index start"')
    }

    預定義好的城市和職位數組如下:

    {
     "city": ["北京","上海","廣州","深圳","杭州","南京","成都","西安","武漢","重慶"],
     "position": ["前端","java","php","ios","android","c++","python",".NET"]
    }

    接下來就是爬蟲主程序部分的分析了。

    分析頁面,找到請求地址

    首先我們打開拉勾網首頁,輸入查詢信息(比如node),然后查看控制臺,找到相關的請求,如圖:

    2217504720-5b3c89dd656e7_articlex[1].png

    這個post請求https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false就是我們所需要的,通過三個請求參數來獲取不同的數據,簡單的分析就可得知:參數first是標注當前是否是第一頁,true為是,false為否;參數pn是當前的頁碼;參數kd是查詢輸入的內容。

    通過superagent請求數據

    首先需要明確得是,整個程序是異步的,我們需要用async.series來依次調用。
    查看分析返回的response:

    43112870-5b3c90261a4c3_articlex[1].png

    可以看到content.positionResult.totalCount就是我們所需要的總頁數
    我們用superagent直接調用post請求,控制臺會提示如下信息:

    {'success': False, 'msg': '您操作太頻繁,請稍后再訪問', 'clientIp': '122.xxx.xxx.xxx'}

    這其實是反爬蟲策略之一,我們只需要給其添加一個請求頭即可,請求頭的獲取方式很簡單,如下:

    3208087083-5b3c97bf640bd_articlex[1].png

    然后在用superagent調用post請求,主要代碼如下:

    // 先獲取總頁數
     (cb) => {
     superagent
     .post(`https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false&city=${city}&kd=${position}&pn=1`)
     .send({
     'pn': 1,
     'kd': position,
     'first': true
     })
     .set(options.options)
     .end((err, res) => {
     if (err) throw err
     // console.log(res.text)
     let resObj = JSON.parse(res.text)
     if (resObj.success === true) {
     totalPage = resObj.content.positionResult.totalCount;
     cb(null, totalPage);
     } else {
     console.log(`獲取數據失敗:${res.text}}`)
     }
     })
     },

    拿到總頁數后,我們就可以通過總頁數/15獲取到pn參數,循環生成所有url并存入urls中:

    (cb) => {
     for (let i=0;Math.ceil(i<totalPage/15);i++) {
     urls.push(`https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false&city=${city}&kd=${position}&pn=${i}`)
     }
     console.log(`${city}的${position}職位共${totalPage}條數據,${urls.length}頁`);
     cb(null, urls);
     },

    有了所有的url,在想爬到所有的數據就不是難事了,繼續用superagent的post方法循環請求所有的url,每一次獲取到數據后,在data目錄下創建json文件,將返回的數據寫入。這里看似簡單,但是有兩點需要注意:

    1. 為了防止并發請求太多而導致被封IP:循環url時候需要使用async.mapLimit方法控制并發為3, 每次請求完都要過兩秒在發送下一次的請求

    2. 在async.mapLimit的第四個參數中,需要通過判斷調用主函數的第三個參數是否存在來區分一下是那種命令輸入,因為對于node index start這個命令,我們使用得是async.mapSeries,每次調用主函數都傳遞了(city, position, callback),所以如果是node index start的話,需要在每次獲取數據完后將null傳遞回去,否則無法進行下一次循環

    主要代碼如下:

    // 控制并發為3
     (cb) => {
     async.mapLimit(urls, 3, (url, callback) => {
     num++;
     let page = url.split('&')[3].split('=')[1];
     superagent
     .post(url)
     .send({
     'pn': totalPage,
     'kd': position,
     'first': false
     })
     .set(options.options)
     .end((err, res) => {
     if (err) throw err
     let resObj = JSON.parse(res.text)
     if (resObj.success === true) {
     console.log(`正在抓取第${page}頁,當前并發數量:${num}`);
     if (!fs.existsSync('./data')) {
     fs.mkdirSync('./data');
     }
     // 將數據以.json格式儲存在data文件夾下
     fs.writeFile(`./data/${city}_${position}_${page}.json`, res.text, (err) => {
     if (err) throw err;
     // 寫入數據完成后,兩秒后再發送下一次請求
     setTimeout(() => {
     num--;
     console.log(`第${page}頁寫入成功`);
     callback(null, 'success');
     }, 2000);
     });
     }
     })
     }, (err, result) => {
     if (err) throw err;
     // 這個arguments是調用controlRequest函數的參數,可以區分是那種爬取(循環還是單個)
     if (arguments[2]) {
     ok = 1;
     }
     cb(null, ok)
     })
     },
     () => {
     if (ok) {
     setTimeout(function () {
     console.log(`${city}的${position}數據請求完成`);
     indexCallback(null);
     }, 5000);
     } else {
     console.log(`${city}的${position}數據請求完成`);
     }
     // exportExcel.exportExcel() // 導出為excel
     }

    導出的json文件如下:
    2625390489-5b3c990dd1e87_articlex[1].png

    json文件導出為excel

    將json文件導出為excel有多種方式,我使用的是node-xlsx這個node包,這個包需要將數據按照固定的格式傳入,然后導出即可,所以我們首先做的就是先拼出其所需的數據格式:

    function exportExcel() {
     let list = fs.readdirSync('./data')
     let dataArr = []
     list.forEach((item, index) => {
     let path = `./data/${item}`
     let obj = fs.readFileSync(path, 'utf-8')
     let content = JSON.parse(obj).content.positionResult.result
     let arr = [['companyFullName', 'createTime', 'workYear', 'education', 'city', 'positionName', 'positionAdvantage', 'companyLabelList', 'salary']]
     content.forEach((contentItem) => {
     arr.push([contentItem.companyFullName, contentItem.phone, contentItem.workYear, contentItem.education, contentItem.city, contentItem.positionName, contentItem.positionAdvantage, contentItem.companyLabelList.join(','), contentItem.salary])
     })
     dataArr[index] = {
     data: arr,
     name: path.split('./data/')[1] // 名字不能包含 \ / ? * [ ]
     }
     })
    
    // 數據格式
    // var data = [
    // {
    // name : 'sheet1',
    // data : [
    // [
    // 'ID',
    // 'Name',
    // 'Score'
    // ],
    // [
    // '1',
    // 'Michael',
    // '99'
    //
    // ],
    // [
    // '2',
    // 'Jordan',
    // '98'
    // ]
    // ]
    // },
    // {
    // name : 'sheet2',
    // data : [
    // [
    // 'AA',
    // 'BB'
    // ],
    // [
    // '23',
    // '24'
    // ]
    // ]
    // }
    // ]
    
    // 寫xlsx
     var buffer = xlsx.build(dataArr)
     fs.writeFile('./result.xlsx', buffer, function (err)
     {
     if (err)
     throw err;
     console.log('Write to xls has finished');
    
    // 讀xlsx
    // var obj = xlsx.parse("./" + "resut.xls");
    // console.log(JSON.stringify(obj));
     }
     );
    }

    導出的excel文件如下,每一頁的數據都是一個sheet,比較清晰明了:
    3676712650-5b3c995aad59d_articlex[1].png

    我們可以很清楚的從中看出目前西安.net的招聘情況,之后也可以考慮用更形象的圖表方式展示爬到的數據,應該會更加直觀!

    總結

    其實整個爬蟲過程并不復雜,注意就是注意的小點很多,比如async的各個方法的使用以及導出設置header等,總之,也是收獲滿滿噠!

    源碼

    gitbug地址: https://github.com/fighting12...

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    node爬取拉勾網數據并導出為excel文件

    node爬取拉勾網數據并導出為excel文件:這篇文章主要介紹了關于node爬取拉勾網數據并導出為excel文件,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下前言之前斷斷續續學習了node.js,今天就拿拉勾網練練手,順便通過數據了解了解最近的招聘行情哈!node方面算是萌新一個吧,希望可
    推薦度:
    標簽: 文件 excel 數據
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 亚洲wwww | 欧美日韩亚洲无线码在线观看 | 一级毛片视频播放 | 国产成人亚洲精品影院 | 精品久久综合一区二区 | 国产福利91精品一区二区 | 日本不卡视频一区二区三区 | 亚洲清纯自偷自拍另类专区 | 日韩欧美高清一区 | 国产精品v欧美精品v日本精 | 国产麻豆91| 91在线 一区 二区三区 | 国产一区二区免费 | 不卡一区二区三区四区 | 中文日韩欧美 | 亚洲色图欧美 | 日韩欧美在线视频 | 交换伦交| 亚洲国产日韩在线一区 | 亚洲自拍另类 | 久久99国产精品成人欧美 | 曰韩在线 | 亚洲综合二区 | 欧美日韩国产在线播放 | 天天舔天天干 | 久草福利社 | 午夜看一级特黄a大片黑 | 伊人久久综合网亚洲 | 国产日韩亚洲欧美 | 久久精品亚洲一区二区三区浴池 | 好看的电影网站亚洲一区 | 国产有码视频 | 精品日韩视频 | 在线播放一区二区三区 | 精品国产免费人成在线观看 | 国产成人精品第一区二区 | 国产高清不卡一区二区三区 | 99久久综合 | 欧美日韩中文字幕在线 | 国产精品va一级二级三级 | 亚洲色欧美 |