node 爬虫

准备工作

Node.js环境搭建

创建工程

选择一个目录,新建一个准备存放工程内容的文件夹demo。

打开终端(windows机器打开CMD命令行),输入npm init,根据提示,逐步输入工程信息,具体示例如下

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (demo) demo
version: (1.0.0)
description: 爬虫
entry point: (index.js)
test command:
git repository:
keywords:
author: huapisong
license: (ISC)
About to write to D:\test\demo\package.json:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "爬虫",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "huapisong",
  "license": "ISC"
}


Is this ok? (yes) yes

此时文件夹下生成了一个package.json文件,其中包含了工程的基本信息以及引用的框架等信息

框架引入

superagent:发起http请求
cheerio:解析http返回的html内容
async:多线程并发控制

安装命令 npm install –save PACKAGE_NAME,执行以下三条命令后,工程目录下多了一个node_modules目录,该目录就是引入的框架内容。

$npm install --save superagent
$npm install --save cheerio
$npm install --save async

编码过程

工程目录下,创建index.js

var superagent = require('superagent');
var cheerio = require('cheerio');
var async = require('async');

var fs = require('fs');
var request = require("request");

console.log('爬虫程序开始运行......');

// 第一步,发起请求,获取的列表
superagent
    .get('http://www.wanfangdata.com.cn/keywords/getNewKeywords.do?keywords=java&resource=all&topNumber=18')
    .set('Accept', 'application/json, text/javascript, */*; q=0.01')
    .set('Content-Type','text/html;charset=UTF-8')
    .end(function(err, res){
        // res.body, res.headers, res.status
        //let body = cheerio.load(res.body);
        // 请求返回后的处理
        // 将response中返回的结果转换成JSON对象
        var words = JSON.parse(res.text).word;
        console.log('抓取的数据:' + JSON.stringify(words));

        async.mapSeries(words,
            function (word, callback) {
                console.log('抓取的数据:' + word);
                // 对每个对象的处理逻辑
                fetchInfo(word, callback);
                console.timeEnd("  耗时");

            },
            function (err, result) {
                console.log('final:\n' + result);
            }
        );
        // 并发遍历 words对象
        /* var words = JSON.parse(res.text);
        async.mapLimit(words, 10,
            function (word, callback) {
                console.log('抓取的数据:' + word);
                // 对每个对象的处理逻辑
                fetchInfo(word, callback);
                console.timeEnd("  耗时");

            },
            function (err, result) {
                console.log('final:\n' + result);
            }
        );*/

    });

var concurrencyCount = 0; // 当前并发数记录
var fetchInfo = function(word, callback){
    console.time('  耗时');
    concurrencyCount++;
    console.log('并发数:', concurrencyCount, ',正在抓取的是', word);

    // 写入文件内容(如果文件不存在会创建一个文件)
    fs.writeFile('./try4.txt', word+'\n', { 'flag': 'a' }, function(err) {
        if (err) {
            console.log('并发数:', concurrencyCount--, 'word', word);
            callback(null, word);
            throw err;
        }
        callback(null, word);
        // 写入成功后读取测试
        /*fs.readFile('./try4.txt', 'utf-8', function(err, data) {
            if (err) {
                throw err;
            }
            console.log(data);
        });*/
    });

}

工程目录下执行命令,node index.js,抓取程序开始执行

 node index.js
爬虫程序开始运行......
抓取的数据:["Java","JAVA","java","Java语言","JAVA语言","Java技术","JAVA技术","Java3D","JavaEE","Java虚拟机","Java EE","JavaBean","Java程序设计","JavaScript","JAVASCRIPT","Javascript","Java Applet"]
抓取的数据:Java
并发数: 1 ,正在抓取的是 Java
 耗时: 1.329ms
抓取的数据:JAVA
并发数: 2 ,正在抓取的是 JAVA
 耗时: 0.646ms
抓取的数据:java
并发数: 3 ,正在抓取的是 java
 耗时: 0.625ms
抓取的数据:Java语言
并发数: 4 ,正在抓取的是 Java语言
 耗时: 0.642ms
抓取的数据:JAVA语言
并发数: 5 ,正在抓取的是 JAVA语言
 耗时: 0.663ms
抓取的数据:Java技术
并发数: 6 ,正在抓取的是 Java技术
 耗时: 0.410ms
抓取的数据:JAVA技术
并发数: 7 ,正在抓取的是 JAVA技术
 耗时: 0.395ms
抓取的数据:Java3D
并发数: 8 ,正在抓取的是 Java3D
 耗时: 0.377ms
抓取的数据:JavaEE
并发数: 9 ,正在抓取的是 JavaEE
 耗时: 0.240ms
抓取的数据:Java虚拟机
并发数: 10 ,正在抓取的是 Java虚拟机
 耗时: 0.346ms
抓取的数据:Java EE
并发数: 11 ,正在抓取的是 Java EE
 耗时: 0.306ms
抓取的数据:JavaBean
并发数: 12 ,正在抓取的是 JavaBean
 耗时: 0.323ms
抓取的数据:Java程序设计
并发数: 13 ,正在抓取的是 Java程序设计
 耗时: 0.326ms
抓取的数据:JavaScript
并发数: 14 ,正在抓取的是 JavaScript
 耗时: 0.306ms
抓取的数据:JAVASCRIPT
并发数: 15 ,正在抓取的是 JAVASCRIPT
 耗时: 0.346ms
抓取的数据:Javascript
并发数: 16 ,正在抓取的是 Javascript
 耗时: 1.027ms
抓取的数据:Java Applet
并发数: 17 ,正在抓取的是 Java Applet
 耗时: 0.955ms
final:
Java,JAVA,java,Java语言,JAVA语言,Java技术,JAVA技术,Java3D,JavaEE,Java虚拟机,Java EE,JavaBean,Java程序设计,JavaScript,JAVASCRIPT,Javascript,Java Applet