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


    安装:

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

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

    参考资料:

  • 相关阅读:
    php原生代码实现explode函数功能
    PHP的命名空间
    高性能索引策略二
    .Net Core缓存组件(Redis)源码解析
    .Net Core缓存组件(MemoryCache)源码解析
    Docker系列之Docker容器(读书笔记)
    Docker系列之Docker镜像(读书笔记)
    .Net Core中的日志组件(Logging)
    .Net Core Cors中间件解析
    .Net Core项目添加日志功能
  • 原文地址:https://www.cnblogs.com/geewonii/p/7138746.html
Copyright © 2020-2023  润新知