一個老同學的故事引發的nodejs 爬蟲

阿飛飛飛發表於2018-08-24

    故事發展

       平靜悠閒的日子,依然是錢少事多,此處想象一個表情。忽然有一天,故事就來了,一個做統計的美女老同學說她懶得自己複製貼上,讓我幫她爬蟲獲取一些文章的內容和制定段落的文字,他們做後續的資料統計和分析,這個忙我當然得幫了,雖然沒爬過。。。哈哈,然後下班之後我就花了幾個小時用自己比較熟悉的nodejs做了這個簡單的小Demo(故事會在文末繼續並附上老同學美照!?)。

    目標:

       爬取該網站(wwwn.cdc.gov/nchs/nhanes…)的右側列表中DocFile下所有的文章的url,然後去爬到每個文章內部的第一段和最後的表格資訊,如下圖:一個老同學的故事引發的nodejs 爬蟲

一個老同學的故事引發的nodejs 爬蟲

下面就是第一篇文章內部第一段,就是我們要爬取內容的一部分,如下:

一個老同學的故事引發的nodejs 爬蟲

(2018.08.31補充)

爬蟲方案分析:

開啟要爬去的主頁,右鍵Doc File下面的某一篇文件,選擇“檢查”可在瀏覽器開發者工具(windows 按F12可直接開啟)中,Element下可看到文件的url地址和整個頁面的DOM結構。

一個老同學的故事引發的nodejs 爬蟲

採用相同的方法,可以開啟其中一篇文章,在文章要爬去的位置右鍵,檢視到文章的Dom結構,獲取到其中內容。

一個老同學的故事引發的nodejs 爬蟲

簡略思路:

定位到文件所在Table---Table下的Doc File---取出Doc File下的文章url---根據url獲取文章內容---選擇文章內我們要爬去的內容所在DOM---格式化處理並儲存在txt中。

採用的node包如下:

cheerio
也要用到node自帶的兩個包 http https
var = require('http');
var = require('https')


npm init 初始化搭建專案,然後安裝npm install cheerio與request ,建立app.js填寫程式碼。

專案目錄:

一個老同學的故事引發的nodejs 爬蟲

直接上原始碼:

var http = require('http');
var https = require('https')
var fs = require('fs');
var cheerio = require('cheerio');
var urlHeader = 'https://wwwn.cdc.gov'
var urlFather = 'https://wwwn.cdc.gov/nchs/nhanes/search/datapage.aspx?Component=Laboratory&CycleBeginYear=2013'
//初始url 

let count = 0;
function findUrlList(x,callback){
    https.get(x, function (res) {   
        var html = '';        //用來儲存請求網頁的整個html內容
        var titles = [];        
        res.setEncoding('utf-8'); //防止中文亂碼
        //監聽data事件,每次取一塊資料
        res.on('data', function (chunk) {   
            html += chunk;
        });
        //監聽end事件,如果整個網頁內容的html都獲取完畢,就執行回撥函式
        res.on('end', function () {
         var $ = cheerio.load(html); //採用cheerio模組解析html
         
         var urlArr = [];
         $('#GridView1 tbody tr').each(function (index, item) {
            let url = urlHeader + $(this).children().next().children('a').attr("href")
            startRequest(url)
            urlArr.push(url)
         })
        console.log(urlArr.length)
        callback()
        });

    }).on('error', function (err) {
        console.log(err);
    });
}

function startRequest(x) {
     //採用http模組向伺服器發起一次get請求      
     https.get(x, function (res) {   
        var html = '';        //用來儲存請求網頁的整個html內容
        var titles = [];        
        res.setEncoding('utf-8'); //防止中文亂碼
        //監聽data事件,每次取一塊資料
        res.on('data', function (chunk) {   
            html += chunk;
        });
        //監聽end事件,如果整個網頁內容的html都獲取完畢,就執行回撥函式
        res.on('end', function () {
         var $ = cheerio.load(html); //採用cheerio模組解析html
         var news_item = {
            //獲取文章的標題
            title: $('div #PageHeader h2').text().trim(),
            url: '文章地址: '+x,
            firstParagraph: '首段:\n'+$('#Component_Description').next().text().trim(),
            codeBookAndFrequencies: '表格資訊: \n'+$('#Codebook').children().text().trim()
            };

        savedContent($,news_item);  //儲存每篇文章的內容及文章標題
        });

    }).on('error', function (err) {
        console.error(err);
    });

}
//該函式的作用:在本地儲存所爬取的新聞內容資源
function savedContent($, news_item) {
    count++;
    let x = '['+count+'] ' + '\n';
    x += news_item.url;
    x = x + '\n'; 
    x += news_item.firstParagraph;
    x = x + '\n'; 
    x += news_item.codeBookAndFrequencies;
    x = x + '\n'; 
    x += '------------------------------------------------------------ \n'; 
    x = x + '\n'; 
    x = x + '\n'; 
    //將新聞文字內容一段一段新增到/data資料夾下,並用新聞的標題來命名檔案
    fs.appendFile('./data/' + news_item.title + '.txt', x, 'utf-8', function (err) {
        if (err) {
            console.log(err);
        }
    });
}

// startRequest(url);      //主程式開始執行
findUrlList(urlFather,() => {
    console.log('work done')
})複製程式碼


命令列 node app.js  跑起來就可看到結果啦!

爬蟲txt結果檢視:

一個老同學的故事引發的nodejs 爬蟲

一個老同學的故事引發的nodejs 爬蟲


API參考:


故事繼續

       對,我花了兩個間斷簡短的晚上幫她做出來了,然後我發現他想要的不是這樣,而是一個更大更多功能的系統,要和他們的R語言系統對接!!!但是又沒有經費,哈哈,那故事就這樣結束了!但是作為一個很有求知慾的程式君,順帶熟練了一下基本的爬蟲,還是很滿足的!謝謝閱讀,希望能給您一些收穫!

美女請收下,你一定不會失望,哈哈哈哈哈?

一個老同學的故事引發的nodejs 爬蟲


相關文章