使用Node.js实现简单的网络爬取

由于最近要实现一个爬取H5游戏的代理服务器,隧看到这么一篇不错的文章(http://blog.miguelgrinberg.com/post/easy-web-scraping-with-nodejs),加之最近在学习Node.js,所以就准备翻译出来加深一下印象。

转载请注明来源:(www.cnblogs.com/xdxer

 

在这篇文章中,我将会向大家展示如何用JavaScript配合Node.js写一个网络爬取的脚本。

网络抓取工具

在大部分情况下,一个网络抓取的脚本只需要一种方法去下载整个页面,然后搜索里面的数据。所有的现代语言都会提供方法去下载网页,或者至少会有人实现了某个library或者一些其他的扩展包,所以这并不是一个难点。然后,要精确定位并且找出在HTML中的数据是比较有难度的。一个HTML页面混杂了许多内容、布局和样式的变量,所以去解释并且识别出那些我们关注的部分是一个挺不容易的工作。

举个例子,考虑如下的HTML页面:

<html>
    <head>...</head>
    <body>
        <div id="content">
            <div id="sidebar">
            ...
            </div>
            <div id="main">
                <div class="breadcrumbs">
                ...
                </div>
                <table id="data">
                    <tr><th>Name</th><th>Address</th></tr>
                    <tr><td class="name">John</td><td class="address">Address of John</td></tr>
                    <tr><td class="name">Susan</td><td class="address">Address of Susan</td></tr>
                </table>
            </div>
        </div>
    </body>
</html>

如果我们需要获取到出现在 id = “data”这个表中的人名,那么应该怎么做呢?

一般的,网页会被下载成一个字符串的形式,然后只需要很简单的对这个网页进行检索,检索出那些出现在<td class = “name”> 之后,以</td>结尾的字符串就可以了。

但是这种方式很容易会获取到不正确的数据。网页可能会有别的table,或者更加糟糕的是,原先的<td class="name"> 变成了 <td align="left" class="name"> ,这将会让我们之前所制定的方案什么都找不到。虽然说网页的变化很容易导致一个爬取脚本失效,但是假如我们可以清楚的知道元素是如何在HTML中组织的,那么我们就不必总是重写我们的爬取脚本,当网页改变的时候。

如果你写过前端的js代码,使用过jQuery,那么你就会发现使用CSS selector 来选择DOM中的元素是一件非常简单的事情。举个例子,在浏览器中,我们可以很简单的爬取到那些名字使用如下的方式:

$(‘#data .name‘).each(function() {
    alert($(this).text());
});

 

介绍一下Node.js

http://nodejs.org (get it here!)

Javascript 是一个嵌入web浏览器的语言,感谢Node.js工程,我们现在可以编写能够独立运行,并且甚至可以作为一个web server 的编程语言。

有很多现成的库,例如jQuery那样的。所以使用Javrscript+Node.js去实现这么一个任务就非常便利了,因为我们可以使用那些现有的操作DOM元素的技术,这些技术在web浏览器上已经应用的比较成熟了。

Node.js有很多的库,它是模块化的。本例子中需要用到两个库,request 和 cheerio。 request主要是用于下载那些网页,cheerio 会在本地生成一棵DOM树,然后提供一个jQuery子集去操作它们。安装Node.js模块需要用到npm操作,类似于Ruby的gem 或者 Python的easy_install

有关于cheerio的一些API 可以参考这一篇CNode社区的文章 (https://cnodejs.org/topic/5203a71844e76d216a727d2e

$ mkdir scraping
$ cd scraping
$ npm install request cheerio

如以上代码所示,首先我们创建了一个目录“scraping”,并且我们在在这个目录下安装了request 和 cheerio模块,事实上,nodejs的模块是可以进行全局性的安装的,但是我更加喜欢locally的安装,安装的效果如下图所示。

那接下来我们就看看如何使用cheerio,来爬取上面的例子中的name,我们创建一个.js文件 example.js,代码如下:

var cheerio = require(‘cheerio‘);
$ = cheerio.load(‘<html><head></head><body><div id="content">
<div id="sidebar"></div><div id="main">
<div id="breadcrumbs"></div><table id="data"><tr>
<th>Name</th><th>Address</th></tr><tr><td class="name">
John</td><td class="address">Address of John</td></tr>
<tr><td class="name">Susan</td><td class="address">
Address of Susan</td></tr></table></div></div></body></html>‘);

$(‘#data .name‘).each(function() {
    console.log($(this).text());
});

输出如下:

$ node example.js
John
Susan

实际例子

http://www.thprd.org/schedules/schedule.cfm?cs_id=15 爬取这个网站中的日程表

代码如下:

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

days = [‘Monday‘, ‘Tuesday‘, ‘Wednesday‘, ‘Thursday‘, ‘Friday‘, ‘Saturday‘, ‘Sunday‘];
pools = {
    ‘Aloha‘: 3,
    ‘Beaverton‘: 15,
    ‘Conestoga‘: 12,
    ‘Harman‘: 11,
    ‘Raleigh‘: 6,
    ‘Somerset‘: 22,
    ‘Sunset‘: 5,
    ‘Tualatin Hills‘: 2
};
for (pool in pools) {
    var url = ‘http://www.thprd.org/schedules/schedule.cfm?cs_id=‘ + pools[pool];

    request(url, (function(pool) { return function(err, resp, body) {
        $ = cheerio.load(body);
        $(‘#calendar .days td‘).each(function(day) {
            $(this).find(‘div‘).each(function() {
                event = $(this).text().trim().replace(/\s\s+/g, ‘,‘).split(‘,‘);
                if (event.length >= 2 && (event[1].match(/open swim/i) || event[1].match(/family swim/i)))
                    console.log(pool + ‘,‘ + days[day] + ‘,‘ + event[0] + ‘,‘ + event[1]);
            });
        });
    }})(pool));
}

输出如下:

$ node thprd.js
Conestoga,Monday,4:15p-5:15p,Open Swim - M/L
Conestoga,Monday,7:45p-9:00p,Open Swim - M/L
Conestoga,Tuesday,7:30p-9:00p,Open Swim - M/L
Conestoga,Wednesday,4:15p-5:15p,Open Swim - M/L
Conestoga,Wednesday,7:45p-9:00p,Open Swim - M/L
Conestoga,Thursday,7:30p-9:00p,Open Swim - M/L
Conestoga,Friday,6:30p-8:30p,Open Swim - M/L
Conestoga,Saturday,1:00p-4:15p,Open Swim - M/L
Conestoga,Sunday,2:00p-4:15p,Open Swim - M/L
Aloha,Monday,1:05p-2:20p,Open Swim
Aloha,Monday,7:50p-8:25p,Open Swim
Aloha,Tuesday,1:05p-2:20p,Open Swim
Aloha,Tuesday,8:45p-9:30p,Open Swim
Aloha,Wednesday,1:05p-2:20p,Open Swim
Aloha,Wednesday,7:50p-8:25p,Open Swim
Aloha,Thursday,1:05p-2:20p,Open Swim
Aloha,Thursday,8:45p-9:30p,Open Swim
Aloha,Friday,1:05p-2:20p,Open Swim
Aloha,Friday,7:50p-8:25p,Open Swim
Aloha,Saturday,2:00p-3:30p,Open Swim
Aloha,Saturday,4:30p-6:00p,Open Swim
Aloha,Sunday,2:00p-3:30p,Open Swim
Aloha,Sunday,4:30p-6:00p,Open Swim
Harman,Monday,4:25p-5:30p,Open Swim*
Harman,Monday,7:30p-8:55p,Open Swim
Harman,Tuesday,4:25p-5:10p,Open Swim*
Harman,Wednesday,4:25p-5:30p,Open Swim*
Harman,Wednesday,7:30p-8:55p,Open Swim
Harman,Thursday,4:25p-5:10p,Open Swim*
Harman,Friday,2:00p-4:55p,Open Swim*
Harman,Saturday,1:30p-2:25p,Open Swim
Harman,Sunday,2:00p-2:55p,Open Swim
Beaverton,Tuesday,10:45a-12:55p,Open Swim (No Diving Well)
Beaverton,Tuesday,8:35p-9:30p,Open Swim No Diving Well
Beaverton,Thursday,10:45a-12:55p,Open Swim (No Diving Well)
Beaverton,Thursday,8:35p-9:30p,Open Swim No Diving Well
Beaverton,Saturday,2:30p-4:00p,Open Swim
Beaverton,Sunday,4:15p-6:00p,Open Swim
Sunset,Tuesday,1:00p-2:30p,Open Swim/One Lap Lane
Sunset,Thursday,1:00p-2:30p,Open Swim/One Lap Lane
Sunset,Sunday,1:30p-3:00p,Open Swim/One Lap Lane
Tualatin Hills,Monday,7:35p-9:00p,Open Swim-Diving area opens at 8pm
Tualatin Hills,Wednesday,7:35p-9:00p,Open Swim-Diving area opens at 8pm
Tualatin Hills,Sunday,1:30p-3:30p,Open Swim
Tualatin Hills,Sunday,4:00p-6:00p,Open Swim
要注意的几个问题: 异步js的作用域问题,还有对网站结构的分析,我会在其他博客中提到。
其实我只翻译了很少的一部分,有兴趣的可以去看一下原文,每一步都说的很仔细。
时间: 2024-10-29 19:08:02

使用Node.js实现简单的网络爬取的相关文章

node.js搭建简单的websocket

1.首先在官网http://www.nodejs.org/下载NODE.JS 2.打开命令行CMD,进入NODEJS\node_modules\的目录,输入npm install socket.io  安装socket.io模块.别急着关掉此CMD窗口,后面有用 3.搭建服务端代码server.js 1 var http = require('http'); 2 var io = require('socket.io'); 3 var cisserver = http.createServer(

node.js搭建简单服务器,用于前端测试websocket链接方法和性能测试

WebSocket简介 谈到Web实时推送,就不得不说WebSocket.在WebSocket出现之前,很多网站为了实现实时推送技术,通常采用的方案是轮询 (Polling)和Comet技术,Comet又可细分为两种实现方式,一种是长轮询机制,一种称为流技术,这两种方式实际上是对轮询技术的改进,这些 方案带来很明显的缺点,需要由浏览器对服务器发出HTTP request,大量消耗服务器带宽和资源.面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并实现真正意义上的

利用node.js搭建简单web服务器的方法教程

前言 使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块.路径解析模块.以及301重定向问题,下面我们就简单讲一下如何来搭建一个简单的Web服务器. 早先不使用web服务器的情况下想要在浏览器端访问本地资源,可以利用firefox浏览器,其可以自己启动一个小型web服务器. 为了让刚接触node的人也能大体看懂,本文的代码我将尽量简化. 准备 首先,

Node.js实现简单的Http服务器

下面来学习如何使用Node.js实现一个简单的Http服务器.在示例代码中我们将看到如何读取请求头.如何设置响应头以及如何设置Http的状态码. var http = require('http'); var server = http.createServer(function(req, res) { var body = "Hello world!"; res.setHeader('Content-Length', body.length); res.setHeader('Cont

vue学习【第三篇】:vue之node.js的简单介绍

什么是node.js 它是可以运行JavaScript的服务平台,可以吧它当做一门后端程序,只是它的开发语言是JavaScript 安装node.js node.js的特性 - 非阻塞IO模型 - 时间驱动 运用的场景 - 高并发低业务 - 实时场景 - 聊天.电子商务.视频直播等 安装地址 http://nodejs.cn/ 判断是否安装成功 node -v 进入编辑状态:node+回车,可以进行一些运算 退出编辑模式:ctrl+d或者ctrl+c两次 npm是一个包管理器,其实是一个命令.使

(二)、node.js的简单操作

现在我们使用命令框来输出一些东西,现在不需要理解,如果看不懂只需要模仿,后续会解释的 我们首先在D盘创建一个文件夹test,然后创建一个test.js的文件 用记事本打开,写console.log('HELLO WORLD');在里面 命令框只输入如下命令 这是在命令框上输出东西 下面我们看看在浏览器中输出东西 我们在创建一个htmltest.js的文件 内容如下: var http = require("http"); http.createServer(function(req, 

Node.js 一个简单的博客实例

原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第一章,由于版本等的原因,在原教程基础上稍加改动即可实现. 环境: win7旗舰版64位 Node.js:0.10.31 mongodb:2.6.4 express:3.× 效果: 注册界面: 登录界面: 登录成功: 发表博客: 发表成功: 源代码: blog/ blog/package.json { "name": "blog", "version"

[js高手之路]Node.js实现简易的爬虫-抓取博客所有文章列表信息

抓取目标:就是我自己的博客:http://www.cnblogs.com/ghostwu/ 需要实现的功能: 抓取博客所有的文章标题,超链接,文章摘要,发布时间 需要用到的库: node.js自带的http库 第三方库:cheerio,这个库就是用来处理dom节点的,他的用法几乎跟jquery用法一模一样,所以有了这个利器,写一个爬虫就非常简单 准备工作: 1,npm init --yes 初始化package.json 2,安装cheerio:npm install cheerio --sav

Python3爬虫(1)_使用Urllib进行网络爬取

网络爬虫 又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. (参考百度百科,详细请见https://baike.baidu.com/item/网络爬虫/5162711?fr=aladdin&fromid=22046949&fromtitle=%E7%88%AC%E8%99%AB) 代码和步骤说明:借鉴http://cuijiahua.com. ht