码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2017-07-10 22:20:19      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:爬取   als   ror   第一个   实现   eject   dom   sar   node   

安装:

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

 

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

参考资料:

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

标签:爬取   als   ror   第一个   实现   eject   dom   sar   node   

原文地址:http://www.cnblogs.com/geewonii/p/7138746.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!