【nodejs爬蟲】使用async控制並發寫一個小說爬蟲

來源:互聯網
上載者:User

標籤:.text   attr   lan   length   內容   split   sync   並發   style   

最近在做一個書城項目,資料用爬蟲爬取,百度了一下找到這個網站,以擇天記這本小說為例。

爬蟲用到了幾個模組,cheerio,superagent,async。

superagent是一個http請求模組,詳情可參考連結。

cheerio是一個有著jQuery類似文法的文檔解析模組,你可以簡單理解為nodejs中的jQuery。

async是一個非同步流程式控制制模組,在這裡我們主要用到async的mapLimit(coll, limit, iteratee, callback)

async.mapLimit(urls, 10, function (url, callback) {        fetchUrl(url, callback, id)      }, function (err, results) {        //TODO      })

第一個參數coll是一個數組,儲存了小說的章節url,第二個參數limit是控制並發數,第三個參數iteratee接受一個回呼函數,該回呼函數的第一個參數就是單獨某一章的url,第二個參數也是一個回呼函數,這個回呼函數執行後會把結果(在這裡就是每一章的內容)儲存到第四個參數callback的results中,results是一個數組,儲存了所有章節的內容。

我們在fetchUrl擷取章節資料。

 

首先我們要根據小說的首頁url擷取所有章節的url儲存到數組urls中:

superagent.get(url)    .charset(‘gbk‘)  //該網站編碼為gbk,用到了superagent-charset    .end(function (err, res) {      var $ = cheerio.load(res.text); //res.text為擷取的網頁內容,通過cheerio的load方法處理後,之後就是jQuery的文法了      let urls = []      total = $(‘#list dd‘).length      console.log(`共${$(‘#list dd‘).length}章`)      $(‘#list dd‘).each(function (i, v) {        if (i < chapters) {          urls.push(‘http://www.zwdu.com‘ + $(v).find(‘a‘).attr(‘href‘))        }      })

fetchUrl函數

function fetchUrl(url, callback, id) {  superagent.get(url)    .charset(‘gbk‘)    .end(function (err, res) {      let $ = cheerio.load(res.text)      //obj為構建的包含章節資訊的對象      callback(null, obj)  //將obj傳遞給第四個參數中的results    })}

完整代碼:

/** * Created by tgxh on 2017/7/4. */const cheerio = require(‘cheerio‘)const express = require(‘express‘)const app = express()const superagent = require(‘superagent‘)require(‘superagent-charset‘)(superagent)const async = require(‘async‘);let total = 0 //總章節數let id = 0 //計數器const chapters = 10 //爬取多少章const url = ‘http://www.zwdu.com/book/8634/‘//去除前後空格和&nbsp;逸出字元function trim(str) {  return str.replace(/(^\s*)|(\s*$)/g, ‘‘).replace(/&nbsp;/g, ‘‘)}//將Unicode轉漢字function reconvert(str) {  str = str.replace(/(&#x)(\w{1,4});/gi, function ($0) {    return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(\w{1,4})(%3B)/g, "$2"), 16));  });  return str}function fetchUrl(url, callback, id) {  superagent.get(url)    .charset(‘gbk‘)    .end(function (err, res) {      let $ = cheerio.load(res.text)      const arr = []      const content = reconvert($("#content").html())      //分析結構後分割html      const contentArr = content.split(‘<br><br>‘)      contentArr.forEach(elem => {        const data = trim(elem.toString())        arr.push(data)      })      const obj = {        id: id,        err: 0,        bookName: $(‘.footer_cont a‘).text(),        title: $(‘.bookname h1‘).text(),        content: arr.join(‘-‘)  //由於需要儲存至mysql中,不支援直接儲存數組,所以將數組拼接成字串,取出時再分割字串即可      }      callback(null, obj)      })}app.get(‘/‘, function (req, response, next) {  superagent.get(url)    .charset(‘gbk‘)    .end(function (err, res) {      var $ = cheerio.load(res.text);      let urls = []      total = $(‘#list dd‘).length      console.log(`共${$(‘#list dd‘).length}章`)      $(‘#list dd‘).each(function (i, v) {        if (i < chapters) {          urls.push(‘http://www.zwdu.com‘ + $(v).find(‘a‘).attr(‘href‘))        }      })      async.mapLimit(urls, 10, function (url, callback) {        id++        fetchUrl(url, callback, id) //需要對章節編號,所以通過變數id來計數      }, function (err, results) {        response.send(results)      })    })})app.listen(3378, function () {  console.log(‘server listening on 3378‘)})

結果如下:

 

 

 

 

【nodejs爬蟲】使用async控制並發寫一個小說爬蟲

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.