zoukankan      html  css  js  c++  java
  • nodejs的简单爬虫

    使用nodejs爬虫豆瓣电影数据,要爬取的页面地址:https://movie.douban.com/top250,简单实现如下:

    'use strict';
    
    // 引入模块
    var https = require('https');
    var fs = require('fs');
    var path = require('path');
    var cheerio = require('cheerio');
    
    // 爬虫的URL信息
    var opt = {
        hostname: 'movie.douban.com',
        path: '/top250',
        port: 443
    };
    
    // 创建http get请求
    https.get(opt, function(res) {
        var html = ''; // 保存抓取到的HTML源码
        var movies = [];  // 保存解析HTML后的数据,即我们需要的电影信息
    
        // 前面说过
        // res 是 Class: http.IncomingMessage 的一个实例
        // 而 http.IncomingMessage 实现了 stream.Readable 接口
        // 所以 http.IncomingMessage 也有 stream.Readable 的事件和方法
        // 比如 Event: 'data', Event: 'end', readable.setEncoding() 等
    
        // 设置编码
        res.setEncoding('utf-8');
    
        // 抓取页面内容
        res.on('data', function(chunk) {
            html += chunk;
        });
    
        res.on('end', function() {
            // 使用 cheerio 加载抓取到的HTML代码
            // 然后就可以使用 jQuery 的方法了
            // 比如获取某个class:$('.className')
            // 这样就能获取所有这个class包含的内容
            var $ = cheerio.load(html);
    
            // 解析页面
            // 每个电影都在 item class 中
            $('.item').each(function() {
                // 获取图片链接
                var movie = {
                    title: $('.title', this).text(), // 获取电影名称
                    star: $('.info .star em', this).text(), // 获取电影评分
                    link: $('a', this).attr('href'), // 获取电影详情页链接
                    picUrl: $('.pic img', this).attr('src') // 获取电影图片链接
                };
    
                // 把所有电影放在一个数组里面
                movies.push(movie);
                // 下载图片
                downloadImg('img/', movie.picUrl);
            });
    
            // 保存抓取到的电影数据
            saveData('data/data.json', movies);
        });
    }).on('error', function(err) {
        console.log(err);
    });
    
    
    /**
     * 保存数据到本地
     *
     * @param {string} path 保存数据的文件
     * @param {array} movies 电影信息数组
     */
    function saveData(path, movies) {
        // 调用 fs.writeFile 方法保存数据到本地
        fs.writeFile(path, JSON.stringify(movies, null, 4), function(err) {
            if (err) {
                return console.log(err);
            }
            console.log('Data saved');
        });
    }
    
    /**
     * 下载图片
     *
     * @param {string} imgDir 存放图片的文件夹
     * @param {string} url 图片的URL地址
     */
    function downloadImg(imgDir, url) {
        https.get(url, function(res) {
            var data = '';
    
            res.setEncoding('binary');
    
            res.on('data', function(chunk) {
                data += chunk;
            });
    
            res.on('end', function() {
                // 调用 fs.writeFile 方法保存图片到本地
                fs.writeFile(imgDir + path.basename(url), data, 'binary', function(err) {
                    if (err) {
                        return console.log(err);
                    }
                    console.log('Image downloaded: ', path.basename(url));
                });
            });
        }).on('error', function(err) {
            console.log(err);
        });
    }
    

    使用eventproxy版:

    var eventproxy = require('eventproxy');
    var superagent = require('superagent');
    var cheerio = require('cheerio');
    var url = require('url');
    
    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 ep = new eventproxy();
    
        ep.after('topic_html', topicUrls.length, function (topics) {
          topics = topics.map(function (topicPair) {
            var topicUrl = topicPair[0];
            var topicHtml = topicPair[1];
            var $ = cheerio.load(topicHtml);
            return ({
              title: $('.topic_full_title').text().trim(),
              href: topicUrl,
              comment1: $('.reply_content').eq(0).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, res.text]);
            });
        });
      });
    

      

  • 相关阅读:
    动态内存Treap
    最大流Dinic
    图的遍历
    Aho_Corasick自动机(AC自动机)
    邻接表
    COJ 3007 Mr.Yang的小助手
    COJ 0601&0602 动态规划(二)及加强
    Codeforces 603A Alternative Thinking
    HDU 2222 Keywords Search
    codeforce--600D
  • 原文地址:https://www.cnblogs.com/vipzhou/p/6416852.html
Copyright © 2011-2022 走看看