前端之 —— node.js摸爬打滚之路(一) 安装: 学习express框架:  简单爬虫的实现: 爬虫并发抓取: 控制爬虫并发数量:

前端之 —— node.js摸爬打滚之路(一)
安装:
学习express框架:
 简单爬虫的实现:
爬虫并发抓取:
控制爬虫并发数量:

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命令行打印爬取指定并发数的多个页面的指定内容。

非教程,只是自己学习的记录,当然也希望可以帮到您。

参考资料: