• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題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關(guān)鍵字專題關(guān)鍵字專題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
    當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

    NodeJS爬蟲實(shí)例之糗事百科

    來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:23:41
    文檔

    NodeJS爬蟲實(shí)例之糗事百科

    NodeJS爬蟲實(shí)例之糗事百科:1.前言分析 往常都是利用 Python/.NET 語(yǔ)言實(shí)現(xiàn)爬蟲,然現(xiàn)在作為一名前端開發(fā)人員,自然需要熟練 NodeJS。下面利用 NodeJS 語(yǔ)言實(shí)現(xiàn)一個(gè)糗事百科的爬蟲。另外,本文使用的部分代碼是 es6 語(yǔ)法。 實(shí)現(xiàn)該爬蟲所需要的依賴庫(kù)如下。 request: 利用 g
    推薦度:
    導(dǎo)讀NodeJS爬蟲實(shí)例之糗事百科:1.前言分析 往常都是利用 Python/.NET 語(yǔ)言實(shí)現(xiàn)爬蟲,然現(xiàn)在作為一名前端開發(fā)人員,自然需要熟練 NodeJS。下面利用 NodeJS 語(yǔ)言實(shí)現(xiàn)一個(gè)糗事百科的爬蟲。另外,本文使用的部分代碼是 es6 語(yǔ)法。 實(shí)現(xiàn)該爬蟲所需要的依賴庫(kù)如下。 request: 利用 g

    1.前言分析

    往常都是利用 Python/.NET 語(yǔ)言實(shí)現(xiàn)爬蟲,然現(xiàn)在作為一名前端開發(fā)人員,自然需要熟練 NodeJS。下面利用 NodeJS 語(yǔ)言實(shí)現(xiàn)一個(gè)糗事百科的爬蟲。另外,本文使用的部分代碼是 es6 語(yǔ)法。

    實(shí)現(xiàn)該爬蟲所需要的依賴庫(kù)如下。

    request: 利用 get 或者 post 等方法獲取網(wǎng)頁(yè)的源碼。 cheerio: 對(duì)網(wǎng)頁(yè)源碼進(jìn)行解析,獲取所需數(shù)據(jù)。

    本文首先對(duì)爬蟲所需依賴庫(kù)及其使用進(jìn)行介紹,然后利用這些依賴庫(kù),實(shí)現(xiàn)一個(gè)針對(duì)糗事百科的網(wǎng)絡(luò)爬蟲。

    2. request 庫(kù)

    request 是一個(gè)輕量級(jí)的 http 庫(kù),功能十分強(qiáng)大且使用簡(jiǎn)單??梢允褂盟鼘?shí)現(xiàn) Http 的請(qǐng)求,并且支持 HTTP 認(rèn)證, 自定請(qǐng)求頭等。下面對(duì) request 庫(kù)中一部分功能進(jìn)行介紹。

    安裝 request 模塊如下:

    npm install request

    在安裝好 request 后,即可進(jìn)行使用,下面利用 request 請(qǐng)求一下百度的網(wǎng)頁(yè)。

    const req = require('request');
    req('http://www.baidu.com', (error, response, body) => {
     if (!error && response.statusCode == 200) {
     console.log(body)
     }
    })

    在沒有設(shè)置 options 參數(shù)時(shí),request 方法默認(rèn)是 get 請(qǐng)求。而我喜歡利用 request 對(duì)象的具體方法,使用如下:

    req.get({
     url: 'http://www.baidu.com'
    },(err, res, body) => {
     if (!err && res.statusCode == 200) {
     console.log(body)
     }
    });

    然而很多時(shí)候,直接去請(qǐng)求一個(gè)網(wǎng)址所獲取的 html 源碼,往往得不到我們需要的信息。一般情況下,需要考慮到請(qǐng)求頭和網(wǎng)頁(yè)編碼。

    網(wǎng)頁(yè)的請(qǐng)求頭網(wǎng)頁(yè)的編碼

    下面介紹在請(qǐng)求的時(shí)候如何添加網(wǎng)頁(yè)請(qǐng)求頭以及設(shè)置正確的編碼。

    req.get({
     url : url,
     headers: {
     "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
     "Host" : "www.zhihu.com",
     "Upgrade-Insecure-Requests" : "1"
     },
     encoding : 'utf-8'
    }, (err, res, body)=>{
     if(!err)
     console.log(body);
    })

    設(shè)置 options 參數(shù), 添加 headers 屬性即可實(shí)現(xiàn)請(qǐng)求頭的設(shè)置;添加 encoding 屬性即可設(shè)置網(wǎng)頁(yè)的編碼。需要注意的是,若 encoding:null ,那么 get 請(qǐng)求所獲取的內(nèi)容則是一個(gè) Buffer 對(duì)象,即 body 是一個(gè) Buffer 對(duì)象。

    上面介紹的功能足矣滿足后面的所需了

    3. cheerio 庫(kù)

    cheerio 是一款服務(wù)器端的 Jquery,以輕、快、簡(jiǎn)單易學(xué)等特點(diǎn)被開發(fā)者喜愛。有 Jquery 的基礎(chǔ)后再來學(xué)習(xí) cheerio 庫(kù)非常輕松。它能夠快速定位到網(wǎng)頁(yè)中的元素,其規(guī)則和 Jquery 定位元素的方法是一樣的;它也能以一種非常方便的形式修改 html 中的元素內(nèi)容,以及獲取它們的數(shù)據(jù)。下面主要針對(duì) cheerio 快速定位網(wǎng)頁(yè)中的元素,以及獲取它們的內(nèi)容進(jìn)行介紹。

    首先安裝 cheerio 庫(kù)

    npm install cheerio

    下面先給出一段代碼,再對(duì)代碼進(jìn)行解釋 cheerio 庫(kù)的用法。對(duì)博客園首頁(yè)進(jìn)行分析,然后提取每一頁(yè)中文章的標(biāo)題。

    首先對(duì)博客園首頁(yè)進(jìn)行分析。如下圖:

    對(duì) html 源代碼進(jìn)行分析后,首先通過 .post_item 獲取所有標(biāo)題,接著對(duì)每一個(gè) .post_item 進(jìn)行分析,使用 a.titlelnk 即可匹配每個(gè)標(biāo)題的 a 標(biāo)簽。下面通過代碼進(jìn)行實(shí)現(xiàn)。

    const req = require('request');
    const cheerio = require('cheerio');
    
    req.get({
     url: 'https://www.cnblogs.com/'
     }, (err, res, body) => {
     if (!err && res.statusCode == 200) {
     let cnblogHtmlStr = body;
     let $ = cheerio.load(cnblogHtmlStr);
     $('.post_item').each((index, ele) => {
     let title = $(ele).find('a.titlelnk');
     let titleText = title.text();
     let titletUrl = title.attr('href');
     console.log(titleText, titletUrl);
     });
     }
     });

    當(dāng)然,cheerio 庫(kù)也支持鏈?zhǔn)秸{(diào)用,上面的代碼也可改寫成:

    let cnblogHtmlStr = body;
    let $ = cheerio.load(cnblogHtmlStr);
    let titles = $('.post_item').find('a.titlelnk');
    titles.each((index, ele) => {
     let titleText = $(ele).text();
     let titletUrl = $(ele).attr('href');
     console.log(titleText, titletUrl);

    上面的代碼非常簡(jiǎn)單,就不再用文字進(jìn)行贅述了。下面總結(jié)一點(diǎn)自己認(rèn)為比較重要的幾點(diǎn)。

    使用 find() 方法獲取的節(jié)點(diǎn)集合 A,若再次以 A 集合中的元素為根節(jié)點(diǎn)定位它的子節(jié)點(diǎn)以及獲取子元素的內(nèi)容與屬性,需對(duì) A 集合中的子元素進(jìn)行 $(A[i]) 包裝,如上面的$(ele) 一樣。在上面代碼中使用 $(ele) ,其實(shí)還可以使用 $(this) 但是由于我使用的是 es6 的箭頭函數(shù),因此改變了 each 方法中回調(diào)函數(shù)的 this 指針,因此,我使用 $(ele); cheerio 庫(kù)也支持鏈?zhǔn)秸{(diào)用,如上面的 $('.post_item').find('a.titlelnk') ,需要注意的是,cheerio 對(duì)象 A 調(diào)用方法 find(),如果 A 是一個(gè)集合,那么 A 集合中的每一個(gè)子元素都調(diào)用 find() 方法,并放回一個(gè)結(jié)果結(jié)合。如果 A 調(diào)用 text() ,那么 A 集合中的每一個(gè)子元素都調(diào)用 text() 并返回一個(gè)字符串,該字符串是所有子元素內(nèi)容的合并(直接合并,沒有分隔符)。

    最后在總結(jié)一些我比較常用的方法。

    first() last() children([selector]): 該方法和 find 類似,只不過該方法只搜索子節(jié)點(diǎn),而 find 搜索整個(gè)后代節(jié)點(diǎn)。

    4. 糗事百科爬蟲

    通過上面對(duì) requestcheerio 類庫(kù)的介紹,下面利用這兩個(gè)類庫(kù)對(duì)糗事百科的頁(yè)面進(jìn)行爬取。

    1、在項(xiàng)目目錄中,新建 httpHelper.js 文件,通過 url 獲取糗事百科的網(wǎng)頁(yè)源碼,代碼如下:

    //爬蟲
    const req = require('request');
    
    function getHtml(url){
     return new Promise((resolve, reject) => {
     req.get({
     url : url,
     headers: {
     "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
     "Referer" : "https://www.qiushibaike.com/"
     },
     encoding : 'utf-8'
     }, (err, res, body)=>{
     if(err) reject(err);
     else resolve(body);
     })
     });
    }
    exports.getHtml = getHtml;

    2、在項(xiàng)目目錄中,新建一個(gè) Splider.js 文件,分析糗事百科的網(wǎng)頁(yè)代碼,提取自己需要的信息,并且建立一個(gè)邏輯通過更改 url 的 id 來爬取不同頁(yè)面的數(shù)據(jù)。

    const cheerio = require('cheerio');
    const httpHelper = require('./httpHelper');
    function getQBJok(htmlStr){
     let $ = cheerio.load(htmlStr);
     let jokList = $('#content-left').children('div');
     let rst = [];
     jokList.each((i, item)=>{
     let node = $(item);
     let titleNode = node.find('h2');
     let title = titleNode ? titleNode.text().trim() : '匿名用戶';
     let content = node.find('.content span').text().trim();
     let likeNumber = node.find('i[class=number]').text().trim();
     rst.push({
     title : title,
     content : content,
     likeNumber : likeNumber
     });
     });
     return rst;
    }
    async function splider(index = 1){
     let url = `https://www.qiushibaike.com/8hr/page/${index}/`;
     let htmlStr = await httpHelper.getHtml(url);
     let rst = getQBJok(htmlStr);
     return rst;
    }
    splider(1);

    在獲取糗事百科網(wǎng)頁(yè)信息的時(shí)候,首先在瀏覽器中對(duì)源碼進(jìn)行分析,定位到自己所需要標(biāo)簽,然后提取標(biāo)簽的文本或者屬性值,這樣就完成了網(wǎng)頁(yè)的解析。

    Splider.js 文件入口是 splider 方法,首先根據(jù)傳入該方法的 index 索引,構(gòu)造糗事百科的 url,接著獲取該 url 的網(wǎng)頁(yè)源碼,最后將獲取的源碼傳入 getQBJok 方法,進(jìn)行解析,本文只解析每條文本笑話的作者、內(nèi)容以及喜歡個(gè)數(shù)。

    直接運(yùn)行 Splider.js 文件,即可爬取第一頁(yè)的笑話信息。然后可以更改 splider 方法的參數(shù),實(shí)現(xiàn)抓取不同頁(yè)面的信息。

    在上面已有代碼的基礎(chǔ)上,使用 koavue2.0 搭建一個(gè)瀏覽文本的頁(yè)面,效果如下:

    源碼已上傳到 github 上。下載地址:https://github.com/StartAction/SpliderQB ;

    項(xiàng)目運(yùn)行依賴 node v7.6.0 以上, 首先從 Github 上面克隆整個(gè)項(xiàng)目。

    git clone https://github.com/StartAction/SpliderQB.git

    克隆之后,進(jìn)入項(xiàng)目目錄,運(yùn)行下面命令即可。

    node app.js

    5. 總結(jié)

    通過實(shí)現(xiàn)一個(gè)完整的爬蟲功能,加深自己對(duì) Node 的理解,且實(shí)現(xiàn)的部分語(yǔ)言都是使用 es6 的語(yǔ)法,讓自己加快對(duì) es6 語(yǔ)法的學(xué)習(xí)進(jìn)度。另外,在這次實(shí)現(xiàn)中,遇到了 Node 的異步控制的知識(shí),本文是采用的是 asyncawait 關(guān)鍵字,也是我最喜歡的一種,然而在 Node 中,實(shí)現(xiàn)異步控制有好幾種方式。關(guān)于具體的方式以及原理,有時(shí)間再進(jìn)行總結(jié)。

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    NodeJS爬蟲實(shí)例之糗事百科

    NodeJS爬蟲實(shí)例之糗事百科:1.前言分析 往常都是利用 Python/.NET 語(yǔ)言實(shí)現(xiàn)爬蟲,然現(xiàn)在作為一名前端開發(fā)人員,自然需要熟練 NodeJS。下面利用 NodeJS 語(yǔ)言實(shí)現(xiàn)一個(gè)糗事百科的爬蟲。另外,本文使用的部分代碼是 es6 語(yǔ)法。 實(shí)現(xiàn)該爬蟲所需要的依賴庫(kù)如下。 request: 利用 g
    推薦度:
    標(biāo)簽: 糗事百科 實(shí)例 糗百
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产高清国产精品国产专区| xxx国产精品视频| 永久无码精品三区在线4| 99久久精品国内| 综合国产精品第一页| 国产欧美精品一区二区三区四区| 激情亚洲一区国产精品| 亚洲精品无码久久不卡| 国产亚洲精品资在线| 亚洲精品无码不卡| 8AV国产精品爽爽ⅴa在线观看| 老司机亚洲精品影院| 久久精品无码专区免费东京热| 精品一久久香蕉国产线看播放| 四虎成人欧美精品在永久在线| 精品久久久久久久无码| 日批日出水久久亚洲精品tv| 国产精品欧美一区二区三区| 久久精品国产只有精品2020| 国产精品毛片VA一区二区三区| 四虎成人精品无码| 在线亚洲精品自拍| 无翼乌无遮挡全彩老师挤奶爱爱帝国综合社区精品 | 无码人妻精品一区二| 精品国产婷婷久久久| 国产精品无打码在线播放 | 亚洲精品国产精品乱码不卡√| 日本精品久久久久影院日本| 久久九九久精品国产免费直播| 精品99久久aaa一级毛片| 狠狠精品久久久无码中文字幕 | 91精品福利在线观看| 一区二区精品在线| 99精品国产一区二区| 国产精品成人久久久久三级午夜电影| 四虎精品成人免费永久| 四虎精品成人免费观看| 国产精品99久久久久久猫咪 | 国自产精品手机在线观看视 | 国产精品一区在线观看你懂的| 9999国产精品欧美久久久久久 |