1. 程式人生 > >前端之 —— node.js摸爬打滾之路(一)

前端之 —— node.js摸爬打滾之路(一)

turn lan name resp function oba ack val 括號

安裝:

window下的安裝,node.js直接上官網下載:https://nodejs.org/en/

選擇LTS,也就是版本號比較低的穩定版,下載下來後運行下載的文件進行安裝;

通過win+R打開cmd命令行:執行以下命令安裝淘寶鏡像:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

學習express框架:

全局安裝express:

cnpm install express -g

建立新文件夾sesson1並進入sesson1:

mkdir sesson1 && cd sesson1

使用npm生成package.json文件:(加-y 可以免去確認)

npm init -y

安裝utility:

cnpm install utility --save

新建app.js文件,復制以下內容:

var express = require(express)  //引入express模塊並賦給變量express
var utility = require(utility) //引入utility庫
var app = express() //加括號表示將express實例化,並賦給變量app

//app.get是express實例的一個方法,常用方法:get、post、put/patch、delete;
//第一個參數是路徑,第二個參數是一個回調函數,函數會接收到兩個對象,分別是 request 和 response,簡寫成:req 和 res;
// req 中包含了瀏覽器傳來的各種信息,query,body,headers等都可以通過 req 對象訪問。 // res 對象,一般通過它向瀏覽器輸出信息。 app.get(/,function(rep,res){var q = req.query.q var md5Value = utility.md5(q) res.send(md5Value) }).listen(3000,function(rep,res){ console.log(app is running at port 3000) })

cmd執行app.js:

node app.js

瀏覽器輸入:http://locallhost:3000/?q=Hello World ,出現Hello World字符串轉md5的值 : 0a4d55a8d778e5022fab701977c5d840bbc486d0

簡單爬蟲的實現:

mkdir lesson2 && cd lesson2
npm init -y
cnpm install cheerio --save-dev

cnpm intsall bluebird --save

新建app.js文件,復制以下內容:

var http = require(‘http‘)
var express = require(‘express‘)
var cheerio = require(‘cheerio‘)
var Promise = require(‘bluebird‘)
var app = express()
var fetchCourseArray = [],pageArray =[]

function getPageAsync(url){
  return new Promise(function(resolve,reject){
      console.log(‘正在爬取...‘+url)

      http.get(url,function(res){
      var html = ‘‘
      res.on(‘data‘,function(data){
          html += data
      })
      res.on(‘end‘,function(){
          resolve(html)
      })
    }).on(‘error‘,function(){
        reject(e)
        console.log(‘任何時候,都不是代碼的錯!‘)
    })
  })
}

pageArray.push(‘http://coderschool.cn/1853.html‘)
pageArray.forEach(function(value,index){
    fetchCourseArray.push(getPageAsync(pageArray[index]))
})

Promise
    .all(fetchCourseArray)
    .then(function(pagesArr){
        pagesArr.forEach(function(html){
            var $ = cheerio.load(html)
            var a = $(‘.post-1853 p a‘)
            itemArr = []
            a.each(function(){
              itemArr.push({
                    title:$(this).text(),
                    href:$(this).attr(‘href‘)
              })
            })
            itemArr.forEach(function(item){
                console.log(item.title +‘: ‘+item.href)
            })
        })    
    })

app.get(‘/‘, function(req,res){
    res.send(itemArr)
}).listen(3000,function(){
    console.log(‘app is listening at port 3000‘)
})

cmd執行:

node app.js

頁面輸出itemArr數組,cmd命令行打印爬取頁面的指定內容。

爬蟲並發抓取:

var cheerio = require(‘cheerio‘)
var eventproxy = require(‘eventproxy‘)
var superagent = require(‘superagent‘)
var url = require(‘url‘)

var cnodeUrl = ‘https://cnodejs.org/‘

superagent.get(cnodeUrl)
    .end(function(err, res) {
        if (err) {
          return console.error(err)
        }
        topicUrls = []
        var $ = cheerio.load(res.text)

        $(‘#topic_list .topic_title‘).each(function(idx, element){
            var $element = $(element)
            var href = url.resolve(cnodeUrl,$element.attr(‘href‘))
            topicUrls.push(href)
        })

        var ep = new eventproxy()
        ep.after(‘topic_html‘,topicUrls.length,function(topics){
            topics = topics.map(function(topicPair){
                var topicUrl = topicPair.topicUrl
                var topicHtml = topicPair.text
                var $ = cheerio.load(topicHtml)
                return ({
                    title: $(‘.topic_full_title‘).text().trim(),
                    href: topicUrl,
                    comment1: $(‘.reply_content‘).eq(0).text().trim(),
                    author1:$(‘.user_name a‘).text().trim(),
                    score1:$(‘.floor .big‘).text().trim()
                })
            })

            console.log(‘final:‘)
            console.log(topics)
        })

        topicUrls.forEach(function(topicUrl){
            superagent.get(topicUrl)
                .end(function(err,res){
                    console.log(‘fetch ‘ + topicUrl + ‘ successful‘)
                    ep.emit(‘topic_html‘,{topicUrl: topicUrl, text: res.text})
                })
        })
    })

cmd執行:

node app.js

cmd命令行打印並發爬取多個頁面的指定內容。

控制爬蟲並發數量:

var cheerio = require(‘cheerio‘)
var superagent = require(‘superagent‘)
var url = require(‘url‘)
var async = require(‘async‘)

var cnodeUrl = ‘https://cnodejs.org/‘

superagent.get(cnodeUrl)
    .end(function(err, res) {
        if (err) {
          return console.error(err)
        }
        var topicUrls = []
        var $ = cheerio.load(res.text)

        $(‘#topic_list .topic_title‘).each(function(idx, element){
            var $element = $(element)
            var href = url.resolve(cnodeUrl,$element.attr(‘href‘))
            topicUrls.push(href)
        })

        var concurrencyCount = 0
        var itemArr = []
        var fetchUrl = function(topicUrl, callback){
            var delay = parseInt((Math.random() * 10000000) % 2000, 10)
            concurrencyCount ++
            console.log(‘並發數:‘+ concurrencyCount,‘正在抓取:‘,topicUrl,‘耗時:‘+delay + ‘ms‘)
            superagent.get(topicUrl)
                .end(function(err,res){
                    var $ = cheerio.load(res.text)
                    var topics = {
                        title: $(‘.topic_full_title‘).text().trim(),
                        href: topicUrl,
                        comment1: $(‘.reply_content‘).eq(0).text().trim(),
                        author1:$(‘.user_name a‘).text().trim(),
                        score1:$(‘.floor .big‘).text().trim()
                    }
                    itemArr.push(topics)
                })
            setTimeout(function(){
                concurrencyCount --
                callback(null,topicUrl + ‘html content‘)
            },delay)
        }

        async.mapLimit(topicUrls,5,
            function(topicUrl, callback){
                fetchUrl(topicUrl, callback)
            },
            function(err, result){
                console.log(‘final:‘)
                console.log(result)
                console.log(itemArr)
            })
    })

cmd執行:

node app1.js

cmd命令行打印爬取指定並發數的多個頁面的指定內容。

非教程,只是自己學習的記錄,當然也希望可以幫到您。

參考資料:

  • 原文地址:https://github.com/alsotang/node-lessons

前端之 —— node.js摸爬打滾之路(一)