nodejs 爬虫笔记

目标:爬取慕课网里面一个教程的视频信息,并将其存入mysql数据库。以http://www.imooc.com/learn/857为例。

一、工具

1.安装nodejs:(操作系统环境:WiN 7 64位)

   在Windows环境下安装相对简单(ps:其他版本我也不太清楚,可以问度娘)

  http://nodejs.org/download/ 链接中下载对应操作系统安装文件(安装最新版本就行)

  按照提示,一路下一步直到安装成功后,在默认安装路径下可以看到(C:\Program Files\nodejs),默认路径在安装的时候可以修改。

  安装成功后,在“命令提示符中”输入:node -v 查看安装版本,输出版本即安装成功

  

2.编码工具:

  WebStorm下载地址: http://www.jetbrains.com/webstorm/,Webstorm用起来很方便,但是我电脑比较卡,我最终还是选择了Sublime,可以在各平台下保持个统一个开发工具,配置方法网上有很多(软件无需注册,使用过程中时不时会弹出需要注册的窗口,取消即可)

   Sublime下载地址: http://www.sublimetext.com/

Sublime配置nodejs环境可参考http://www.cnblogs.com/zhongweiv/p/nodejs_environment.html

二、相关模块

  • 获取网页内容(http\request\superagent等)
  • 筛选网页信息(cheerio)
  • 输出或存储信息(console\fs\mongodb\mysql等)

1、使用 request 模块来获取网页内容

request 是一个用来简化 HTTP 请求操作的模块,其功能强大而且使用方法简单,以下 是一个通过 GET 方法来获取某个URL的内容的例子:

var request = require(‘request‘);

// 通过 GET 请求来读取 http://cnodejs.org/ 的内容
request(‘http://cnodejs.org/‘, function (error, response, body) {
  if (!error && response.statusCode == 200) {
    // 输出网页内容
    console.log(body);
  }
});

如果是其他的请求方法,或者需要指定请求头等信息,可以在第一个参数中传入一个对象来 指定,比如:

var request = require(‘request‘);

request({
  url:    ‘http://cnodejs.org/‘,   // 请求的URL
  method: ‘GET‘,                   // 请求方法
  headers: {                       // 指定请求头
    ‘Accept-Language‘: ‘zh-CN,zh;q=0.8‘,         // 指定 Accept-Language
    ‘Cookie‘: ‘__utma=4454.11221.455353.21.143;‘ // 指定 Cookie
  }
}, function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body) // 输出网页内容
  }
});

本文中仅用到了 request 模块很少的部分,其具体的使用方法可以浏览该模块的主页来获取详细的使用说明:https://npmjs.org/package/request

2、使用 cheerio 模块来提取网页中的数据

cheerio 是一个 jQuery Core 的子集,其实现了 jQuery Core 中浏览器无关的 DOM 操作 API,以下是一个简单的示例:

var cheerio = require(‘cheerio‘);

// 通过 load 方法把 HTML 代码转换成一个 jQuery 对象
var $ = cheerio.load(‘<h2 class="title">Hello world</h2>‘);

// 可以使用与 jQuery 一样的语法来操作
$(‘h2.title‘).text(‘Hello there!‘);
$(‘h2‘).addClass(‘welcome‘);

console.log($.html());
// 将输出 <h2 class="title welcome">Hello there!</h2>

简单来说,cheerio就是服务器端的jQuery,去掉了jQuery的一些效果类和请求类等等功能后,仅保留核心对dom操作的部分,因此能够对dom进行和jQuery一样方便的操作。它是我们筛选数据的利器——把多余的html标签去掉,只留下我们想要的内容的重要工具。需要注意的是,cheerio 并不支持所有 jQuery 的查询语法,比如 $(‘a:first‘) 会报错 ,只能写成  $(‘a‘).first() ,在使用的时候需要注意。jQuery的相关选择器可以参考http://www.cnblogs.com/xiaxuexiaoab/p/7091527.html

cheerio 模块的详细使用方法可以访问该模块的主要来获取: https://npmjs.org/package/cheerio

3、使用 mysql 模块来将数据储存到数据库

我使用的是mysql连接池,具体的使用方法可以参考https://github.com/felixge/node-mysql

mysql 模块内置了连接池机制,以下是一个简单的使用示例:

var mysql = require(‘mysql‘);

// 创建数据库连接池
var pool  = mysql.createPool({
  host:           ‘localhost‘, // 数据库地址
  user:           ‘root‘,      // 数据库用户
  password:        ‘‘,         // 对应的密码
  database:        ‘example‘,  // 数据库名称
  connectionLimit: 10          // 最大连接数,默认为10
});

// 在使用 SQL 查询前,需要调用 pool.getConnection() 来取得一个连接
pool.getConnection(function(err, connection) {
  if (err) throw err;

  // connection 即为当前一个可用的数据库连接
});

4、使用 async 模块来简化异步流程控制

async 是一个使用比较广泛的 JavaScript 异步流程控制模块,除了可以在 Node.js 上运行外,其还可以在浏览器端运行。 async模块提供了约 20 多个实用的函数来 帮助我们理清在使用 Node.js 过程中各种复杂回调。

可以参考:http://blog.csdn.net/zzwwjjdj1/article/details/51857959

关于 async 模块的详细使用方法可以访问该模块的主页来获取: https://npmjs.org/package/async.

三、开始爬虫

1、初始化项目

在喜欢的目录下创建一个文件夹,我在D盘创建文件夹并命名为crawler;在DOS下cd到该目录,运行npm init 初始化,此时需要填写一些项目信息,你可以根据情况填写,当然也可以一路回车。创建完项目后,会生成一个package.json的文件。该文件包含了项目的基本信息。然后安装第三方包:

npm install request cheerio mysql async -save

–save的目的是将项目对该包的依赖写入到package.json文件中。此时,package.json文件如下:

{
  "name": "crawler",
  "version": "1.0.0",
  "description": "crawler and mysql",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "async": "^2.5.0",
    "cheerio": "^1.0.0-rc.1",
    "mysql": "^2.13.0",
    "request": "^2.81.0"
  }
}

2、分析页面

打开http://www.imooc.com/learn/857,可以发现课程如下:

我习惯使用Google浏览器,打开网页后点击检查,可以查看该网页相关部分的html代码如下:

    

3、获取视频信息

我们需要从这段HTML中获取视频的名称name,id,url,时长duration以及所属章节title。利用jQuery的方法,可以通过$(‘.video li a‘)来获取所有视频的a标签,然后从中提取name,duration,url和id,所属章节的话要转到a标签的曾祖父。在crawler目录下新建video.js,在sublime-text中编辑程序如下:

var request = require(‘request‘);
var cheerio = require(‘cheerio‘);

var url = ‘http://www.imooc.com/learn/857‘;

function videocrawler(url,callback){
       //获取页面
    request(url,function(err,res){
        if(err){
            callback(err);
        }

        var $ = cheerio.load(res.body.toString()); //利用cheerio对页面进行解析

        var videoList = [];

        $(‘.video li a‘).each(function(){
            var $title = $(this).parent().parent().parent().text().trim();
            var title = $title.split(‘\n‘);
            var text = $(this).text().trim();
            text = text.split(‘\n‘);
            //console.log(text);
            var time = text[1].match(/\((\d+\:\d+)\)/);
            var item={
                title : title[0],
                url : ‘http://www.imooc.com‘+$(this).attr(‘href‘),
                name : text[0],
                duration : time[1]
            };
            var s = item.url.match(/video\/(\d+)/);
            //console.log(s);
            if(Array.isArray(s)){
                item.id = s[1];
                videoList.push(item);
            }
        });

        callback(null,videoList);
    });
}

videocrawler(url,function(err,videoList){
       if(err){
           return console.log(err);
       }
       console.log(videoList);
});

配置好node.js环境后(配置参考http://www.cnblogs.com/zhongweiv/p/nodejs_environment.html), 点击ctrl+s进行保存,再点击ctrl+b运行(也可以在DOS下输入node video运行)显示如下:

我们已经得到了视频相关信息,接下来我们将其存入mysql。

4、数据存入mysql

新建数据库muke,然后新建数据表video,在DOS下输入use muke后,创建数据库表:

CREATE TABLE `video` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `url` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `duration` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

然后在crawler文件夹下新建save.js,先利用sublime编辑代码如下:

var mysql = require(‘mysql‘);
var async = require(‘async‘);

var pool = mysql.createPool({
    host : ‘localhost‘,
    user : ‘root‘,
    password : ‘z2457098495924‘,
    database : ‘muke‘
});

pool.getConnection(function(err,connection){
    if(err){
        console.log(err);
    }
    connection.query(‘show tables‘,function(err,result){
         if(err){
             return console.log(‘show tables error:‘+err.message);
         }
         return console.log(result);
    });
    connection.release();
});

运行后输出如下图,其中content是muke数据库下的另外一个表。

此时说明数据库已经连接成功。接下来继续编辑save.js如下:

var mysql = require(‘mysql‘);
var async = require(‘async‘);

var pool = mysql.createPool({
    host : ‘localhost‘,
    user : ‘root‘,
    password : ‘z2457098495924‘,
    database : ‘muke‘
});

exports.videoSave = function(list,callback){

    pool.getConnection(function(err,connection){
        if(err){
            return callback(err);
        }
        var insertsql = ‘insert into video(id,title,url,name,duration) values(?,?,?,?,?)‘;
        async.eachSeries(list,function(item,next){
            connection.query(insertsql,[item.id,item.title,item.url,item.name,item.duration],next);
        },callback);
        connection.release();
    });
};

修改video.js如下

var request = require(‘request‘);
var cheerio = require(‘cheerio‘);

exports.videocrawler = function(url,callback){
    request(url,function(err,res){
        if(err){
            callback(err);
        }

        var $ = cheerio.load(res.body.toString());

        var videoList = [];

        $(‘.video li a‘).each(function(){
            var $title = $(this).parent().parent().parent().text().trim();
            var title = $title.split(‘\n‘);
            var text = $(this).text().trim();
            text = text.split(‘\n‘);
            //console.log(text);
            var time = text[1].match(/\((\d+\:\d+)\)/);
            var item={
                title : title[0],
                url : ‘http://www.imooc.com‘+$(this).attr(‘href‘),
                name : text[0],
                duration : time[1]
            };
            var s = item.url.match(/video\/(\d+)/);
            //console.log(s);
            if(Array.isArray(s)){
                item.id = s[1];
                videoList.push(item);
            }
        });

        callback(null,videoList);
    });
}

然后在crawler目录下新建index.js文件,编辑代码如下:

var async = require(‘async‘);var video = require(‘./video‘);
var save = require(‘./save‘);
var url = ‘http://www.imooc.com/learn/857‘;
var videolist;

async.series([
        //获取视频信息
        function(done){
            video.videocrawler(url,function(err,list){
                videolist = list;
                done(err);
            });
        },
        //保存视频信息
        function(done){
            save.videoSave(videolist,done);
        },

    ],function(err){
    if(err){
        console.log(err);
    }
    console.log(‘完成‘);
    process.exit(0);
})

点击运行后会输出 ‘’完成‘’。然后利用可视化工具Navicat 查看video数据表可以看到信息已经存入。

四、总结

通过训练,对request、cheerio、async、mysql等模块有了初步的了解,也熟悉了下node爬虫的基本过程,但保存数据时,存入数据库还需判断数据是否存在、去重等问题。

欢迎评论,转载请注明地址。

时间: 2024-10-05 21:22:27

nodejs 爬虫笔记的相关文章

nodejs爬虫笔记(二)

node爬虫代理设置 最近想爬取YouTube上面的视频信息,利用nodejs爬虫笔记(一)的方法,代码和错误如下 var request = require('request'); var cheerio = require('cheerio');**** var url = 'https://www.youtube.com '; function crawler(url,callback){ var list = []; request(url,function(err,res){ if(e

nodejs爬虫笔记(五)---利用nightmare模拟点击下一页

目标 以腾讯滚动新闻为例,利用nightmare模拟点击下一页,爬取所有页面的信息.首先得感谢node社区godghdai的帮助,开始接触不太熟悉nightmare,感觉很高大上,自己写代码的时候问题也很多,多亏大神的指点. 一.选择模拟的原因 腾讯滚动新闻,是每六十秒更新一次,而且有下一页.要是直接获取页面的话得一页一页的获取,不太方便,又想到了找数据接口,然后通过请求得到数据,结果腾讯新闻的数据接口是加密的,这种想法又泡汤了.因而想到笔记(四)中模拟加载更多的模块,看利用nightmare这

nodejs爬虫笔记(三)

思路:通过笔记(二)中代理的设置,已经可以对YouTube的信息进行爬取了,这几天想着爬取网站下的视频信息.通过分析YouTube,可以从订阅号入手,先选择几个订阅号,然后爬取订阅号里面的视频分类,之后进入到每个分类下的视频列表,最后在具体到每一个视频,获取需要的信息.以订阅号YouTube 电影为例. 一.爬取YouTube 电影里面的视频分类列表 打开订阅号,我们可以发现订阅号下有许多视频分类如下图所示,接下来可以解析该订阅号信息,把视频分类的URL和名称爬取下来. 接下来我们通过浏览器点击

nodejs学习笔记(基于v7.4.0)

nodejs学习笔记 一.buffer: 全局对象(单例   Buffer.from   Buffer.alloc   Buffer.allocUnsafe ) 编码类型 描述 ascii 仅仅用于7位ascall数据编码,速度快,如果设置了将会剥离高位 utf8 多字节的编码的Unicode字符,网页文档大部分默认都为它. utf16le 小端编码的Unicode字符,2或者4个字节 ucs2 utf16le的别名 base64 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之

nodejs学习笔记_nodejs和PHP在基础架构上的差别--共享状态的并发

绝大多数对于Node.js的讨论都把关注点放在了处理高并发能力上,做开发的时候一定要明确node内部做出的权衡,以及node应用性能好的原因. node 为javascript引入了一个复杂的概念,:共享状态的并发. node採用一个长期执行的进程 而php在apache中会产生多个进程 例如以下图所看到的: 代码验证: PHP: <?php $i = 0; $i++; echo $i nodejs: var http = require('http'); var i=0; http.creat

nodejs学习笔记之安装、入门

由于项目需要,最近开始学习nodejs.在学习过程中,记录一些必要的操作和应该注意的点. 首先是如何安装nodejs环境?(我用的是windows 7环境,所以主要是windows 7的例子.如果想看linux下的安装可以参考http://www.cnblogs.com/meteoric_cry/archive/2013/01/04/2844481.html) 1. nodejs提供了一些安装程序,可以去官网(http://nodejs.org/download/)按照自己的机器进行下载,下载完

Nodejs爬虫进阶教程之异步并发控制

Nodejs爬虫进阶教程之异步并发控制 之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回答才会再加载一部分,所以说如果直接发送一个问题的请求链接,取得的页面是不完整的.还有就是我们通过发送链接下载图片的时候,是一张一张来下的,如果图片数量太多的话,真的是下到你睡完觉它还在下,而且我们用nodejs写的爬虫,却竟然没有用到nodejs最牛逼的异步并发的特性,太浪费了啊. 思路 这次的的爬

NodeJS爬虫系统初探

NodeJS爬虫系统 NodeJS爬虫系统 0. 概论 爬虫是一种自动获取网页内容的程序.是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上是针对爬虫而做出的优化. robots.txt是一个文本文件,robots.txt是一个协议,不是一个命令.robots.txt是爬虫要查看的第一个文件.robots.txt文件告诉爬虫在服务器上什么文件是可以被查看的,搜索机器人就会按照该文件中的内容来确定访问的范围. 一般网站的robots.txt查找方法: 例如www.qq.com http://ww

Nodejs 爬虫简单编写

nodejs 爬虫原理,先用request请求页面内容,把内容获取到并iconv-lite设置编码格式,再用cheerio进行类似dom操作合并内容,转换写入文件中 1)获取单页面数据: var fs = require('fs') var request = require('request') var iconvLite = require('iconv-lite') var cheerio = require('cheerio') //请求 request({ url:'https://g