node爬蟲快速入門

node爬蟲

初入前端,剛剛接觸node,對於耳聞已久的node爬蟲很是神往,因此有了這篇文章, 項目代碼在文章末尾

需求

抓取天涯論壇重慶地區板塊的文章列表信息。html

使用工具

  1. node.js
  2. superagent(客戶端請求代理模塊)
  3. cheerio(爲服務器特別定製的,快速、靈活、實施的jQuery核心實現)

安裝並使用cheerio,superagent模塊

安裝
npm install superagent cheerio --save
在項目中引入cheerio,superagent
const superagent = require('superagent')
const cheerio = require('cheerio')
指定須要抓取的域名
const mainUrl = 'http://bbs.tianya.cn'  //天涯論壇主域名
let url = '/list-45-1.shtml'    //重慶區域域名
請求數據
superagent.get(mainUrl + url).end(function (err, res) {
        // 拋錯攔截
        if (err) {
            return
            throw Error(err)
        }
        console.log(res)
    }

分析頁面結構

對頁面內容進行分析,提取對咱們須要的內容

如下圖片是頁面信息
前端

  1. 咱們須要的列表在class爲mt5的div下。
  2. 整個網頁有多個mt5,繼續向下找。
  3. 每一欄信息在('.mt5 table tbody tr')下。
  4. 調用cheerio選取('.mt5 table tbody tr')node

    let $ = cheerio.load(res.text)
    $('.mt5 table tbody tr').each((index, item)=>{
    //這裏是每一項的信息
    })
  5. 找到了信息,下面對找到的信息進行解析

解析數據

找到須要解析的數據,對數據進行解析,保存咱們須要的數據
let $ = cheerio.load(res.text)
        let data = []   //存儲抓去到的數據
        $('.mt5 table tbody tr').each((index, item) => {
            let _this = $(item)
            //根據頁面判斷是不是文章
            if ($(_this.children()[0]).hasClass('td-title')) {
                //對數據進行存儲
                let obj
                let title = $(_this.find('.td-title')).find('span').next().text()
                // let text = $(_this.find('a')[0]).text()  //另外一種選擇器
                let type = $(_this.find('.td-title')).find('.face').attr('title')
                let goto = $(_this.find('.td-title')).find('span').next().attr('href')
                let author = $(_this.children()[1]).text()
                let point = $(_this.children()[2]).text()
                let time = $(_this.children()[3]).text()
                obj = {
                    title: title,
                    type: type,
                    url: mainUrl + goto,
                    author: author,
                    point: point,
                    time: time
                }
                if (obj.title != "") {
                    //判斷若是有內容,則推送到data中
                    data.push(obj)
                }
            }
        })

存儲數據到本地

此時須要把data中保存的數據存到想要保存的文件中須要用到node的fs模塊

1.引入fs模塊git

const fs = require('fs')

2.存儲數據到本地github

在根目錄下建立data文件夾數據庫

fs.writeFile(__dirname + '/data/articleLists.json', JSON.stringify({
                status: 0,
                data: data
            }), function (err) {
                if (err) {
                    console.log(err)
                } else {
                  console.log("寫入文章列表完成")
                }
            })

如今爬蟲會把爬到的數據存儲到本地了
ok,到這裏咱們的爬蟲已經完成了,接下來咱們須要對它進行優化npm

讓爬蟲更聰明

如今咱們的爬蟲只能爬取當前頁的信息,咱們來改一下,讓它也能翻頁

分析翻頁按鈕,天涯論壇的列表也的下一頁按鈕中有一個a標籤,裏邊的url加上以前咱們記錄的mainUrl就是下一頁的標籤。因此,在爬蟲爬取完本頁的數據後,讓爬蟲向下一頁的連接發一個新的請求就能夠繼續爬去了。json

//單次讀取後,找到下一頁的連接,繼續抓取下一頁的數據
        let nextPage = $('.mt5').next().find('.short-pages-2 .links')
        nextPage.children().each((index, item) => {
            if ($(item).text() === '下一頁') {
                let url = $(item).attr("href")
                getData(url)    //剛纔咱們請求數據的方法,命名爲這個函數
            }
        })

如今,爬蟲讀取完當前頁數據後就會繼續爬取下一頁的數據。服務器

完成代碼

最後我還增長了一個頁碼,每一頁數據,單獨進行記錄。下面是完整的代碼
const superagent = require('superagent')
const cheerio = require('cheerio')
const fs = require('fs')

const mainUrl = 'http://bbs.tianya.cn'  //天涯論壇主域名
let url = '/list-45-1.shtml'    //重慶區域域名

let index = 1   //記錄頁碼數
//發送請求獲取頁面資源方法
let getData = (url) => {
    // 使用superagent請求頁面數據
    superagent.get(mainUrl + url).end(function (err, res) {
        // 拋錯攔截
        if (err) {
            return
            throw Error(err)
        }
        // 請求數據後使用cheerio解析數據
        let $ = cheerio.load(res.text)
        let data = []   //存儲抓去到的數據
        $('.mt5 table tbody tr').each((index, item) => {
            let _this = $(item)
            //根據頁面判斷是不是文章
            if ($(_this.children()[0]).hasClass('td-title')) {
                //對數據進行存儲
                let obj
                let title = $(_this.find('.td-title')).find('span').next().text()
                // let text = $(_this.find('a')[0]).text()  //另外一種選擇器
                let type = $(_this.find('.td-title')).find('.face').attr('title')
                let goto = $(_this.find('.td-title')).find('span').next().attr('href')
                let author = $(_this.children()[1]).text()
                let point = $(_this.children()[2]).text()
                let time = $(_this.children()[3]).text()
                obj = {
                    title: title,
                    type: type,
                    url: mainUrl + goto,
                    author: author,
                    point: point,
                    time: time
                }
                if (obj.title != "") {
                    //判斷若是有內容,則推送到data中
                    data.push(obj)
                }
            }
        })
        if (data.length > 0) {  //判斷data中是否有內容
            //使用fs模塊對data中的數據進行儲存,也可使用數據庫進行操做
            fs.writeFile(__dirname + '/data/articleLists' + index + '.json', JSON.stringify({
                status: 0,
                data: data
            }), function (err) {
                if (err) {
                    console.log(err)
                } else {
                    console.log("寫入文章列表完成, 當前頁碼:", index)
                    index++
                }
            })
        }
        //單次讀取後,找到下一頁的連接,繼續抓取下一頁的數據
        let nextPage = $('.mt5').next().find('.short-pages-2 .links')
        nextPage.children().each((index, item) => {
            if ($(item).text() === '下一頁') {
                let url = $(item).attr("href")
                getData(url)
            }
        })
    })
}
//初次執行數據抓取
getData(url)
好了本次node爬蟲快速入門文章到這裏就結束了,可是這個爬蟲還有不少地方須要完善,之後我會爲你們帶來更詳細的爬蟲教程
相關文章
相關標籤/搜索