写在之前

  很多人都有做数据采集的需求,用不同的语言,不同的方式都能实现,我以前也用C#写过,主要还是发送各类请求和正则解析数据比较繁琐些,总体来说没啥不好的,就是效率要差一些,

  用nodejs写采集程序还是比较有效率(可能也只是相对C#来说),今天主要用一个示例来说一下使用nodejs实现数据采集器,主要使用到request和cheerio。

  request :用于http请求

  https://github.com/request/request

  cheerio:用于提取request返回的html中需要的信息(和jquery用法一致)

  https://github.com/cheeriojs/cheerio

示例

  单独去说API用法没什么意思也没必要记住全部API,下面开始示例

  还是说点闲话:

  nodejs开发工具还是很多,以前我也很推荐sublime,自从微软推出了Visual Studio Code后就转用它去做nodejs开发。

  用它开发还是比较舒服的,免配置、启动快、自动补全、查看定义和引用、搜索快等,有VS的一贯风格,应该会越做越好,所以推荐一下^_^!

  示例要求

  从 http://36kr.com/ 中抓取其中文章的“标题”、“地址”、“发布时间”、“封面图片”

  采集器

  1.建立项目文件夹sampleDAU

  2.建立package.json文件

{
"name": "Wilson_SampleDAU",
"version": "0.0.1",
"private": false,
"dependencies": {
"request":"*",
"cheerio":"*"
}
}

  3.在终端中用npm安装引用 

cd 项目根目录
npm install

  4.建立app.js编写采集器代码

  首先要用浏览器打开要采集的URL,使用开发者工具查看HTML结构,然后根据结构写解析代码

/*
* 功能: 数据采集
* 创建人: Wilson
* 时间: 2015-07-29
*/
var request = require('request'),
cheerio = require('cheerio'),
URL_36KR = 'http://36kr.com/'; //36氪 /* 开启数据采集器 */
function dataCollectorStartup() {
dataRequest(URL_36KR);
} /* 数据请求 */
function dataRequest(dataUrl)
{
request({
url: dataUrl,
method: 'GET'
}, function(err, res, body) {
if (err) {
console.log(dataUrl)
console.error('[ERROR]Collection' + err);
return;
} switch(dataUrl)
{
case URL_36KR: dataParse36Kr(body); break;
} });
} /* 36kr 数据解析 */
function dataParse36Kr(body)
{
console.log('============================================================================================');
console.log('======================================36kr==================================================');
console.log('============================================================================================'); var $ = cheerio.load(body); var articles = $('article') for (var i = 0; i < articles.length; i++) {
var article = articles[i];
var descDoms = $(article).find('.desc'); if(descDoms.length == 0)
{
continue;
} var coverDom = $(article).children().first();
var titleDom = $(descDoms).find('.info_flow_news_title');
var timeDom = $(descDoms).find('.timeago'); var titleVal = titleDom.text();
var urlVal = titleDom.attr('href');
var timeVal = timeDom.attr('title');
var coverUrl = coverDom.attr('data-lazyload'); //处理时间
var timeDateSecs = new Date(timeVal).getTime() / 1000; if(urlVal != undefined)
{
console.info('--------------------------------');
console.info('标题:' + titleVal);
console.info('地址:' + urlVal);
console.info('时间:' + timeDateSecs);
console.info('封面:' + coverUrl);
console.info('--------------------------------');
}
};
} dataCollectorStartup();

  测试结果

  这个采集器就完成了,其实就是request一个get请求,请求回调中会返回body即HTML代码,通过cheerio库以jquery库语法一样操作解析,取出想要的数据!

加入代理

  做一个采集器DEMO上面就基本完成了。如果需要长期使用为了防止网站屏蔽,还是需要加入一个代理列表

  为示例我从网上的免费代理中提出一些做示例,制作成proxylist.js,其中提供一个随机取一条代理的函数

proxylist.js

var PROXY_LIST = [{"ip":"111.1.55.136","port":"55336"},{"ip":"111.1.54.91","port":"55336"},{"ip":"111.1.56.19","port":"55336"}
,{"ip":"112.114.63.16","port":"55336"},{"ip":"106.58.63.83","port":"55336"},{"ip":"119.188.133.54","port":"55336"}
,{"ip":"106.58.63.84","port":"55336"},{"ip":"183.95.132.171","port":"55336"},{"ip":"11.12.14.9","port":"55336"}
,{"ip":"60.164.223.16","port":"55336"},{"ip":"117.185.13.87","port":"8080"},{"ip":"112.114.63.20","port":"55336"}
,{"ip":"188.134.19.102","port":"3129"},{"ip":"106.58.63.80","port":"55336"},{"ip":"60.164.223.20","port":"55336"}
,{"ip":"106.58.63.78","port":"55336"},{"ip":"112.114.63.23","port":"55336"},{"ip":"112.114.63.30","port":"55336"}
,{"ip":"60.164.223.14","port":"55336"},{"ip":"190.202.82.234","port":"3128"},{"ip":"60.164.223.15","port":"55336"}
,{"ip":"60.164.223.5","port":"55336"},{"ip":"221.204.9.28","port":"55336"},{"ip":"60.164.223.2","port":"55336"}
,{"ip":"139.214.113.84","port":"55336"} ,{"ip":"112.25.49.14","port":"55336"},{"ip":"221.204.9.19","port":"55336"}
,{"ip":"221.204.9.39","port":"55336"},{"ip":"113.207.57.18","port":"55336"} ,{"ip":"112.25.62.15","port":"55336"}
,{"ip":"60.5.255.143","port":"55336"},{"ip":"221.204.9.18","port":"55336"},{"ip":"60.5.255.145","port":"55336"}
,{"ip":"221.204.9.16","port":"55336"},{"ip":"183.232.82.132","port":"55336"},{"ip":"113.207.62.78","port":"55336"}
,{"ip":"60.5.255.144","port":"55336"} ,{"ip":"60.5.255.141","port":"55336"},{"ip":"221.204.9.23","port":"55336"}
,{"ip":"157.122.96.50","port":"55336"},{"ip":"218.61.39.41","port":"55336"} ,{"ip":"221.204.9.26","port":"55336"}
,{"ip":"112.112.43.213","port":"55336"},{"ip":"60.5.255.138","port":"55336"},{"ip":"60.5.255.133","port":"55336"}
,{"ip":"221.204.9.25","port":"55336"},{"ip":"111.161.35.56","port":"55336"},{"ip":"111.161.35.49","port":"55336"}
,{"ip":"183.129.134.226","port":"8080"} ,{"ip":"58.220.10.86","port":"80"},{"ip":"183.87.117.44","port":"80"}
,{"ip":"211.23.19.130","port":"80"},{"ip":"61.234.249.107","port":"8118"},{"ip":"200.20.168.140","port":"80"}
,{"ip":"111.1.46.176","port":"55336"},{"ip":"120.203.158.149","port":"8118"},{"ip":"70.39.189.6","port":"9090"}
,{"ip":"210.6.237.191","port":"3128"},{"ip":"122.155.195.26","port":"8080"}]; module.exports.GetProxy = function () { var randomNum = parseInt(Math.floor(Math.random() * PROXY_LIST.length));
var proxy = PROXY_LIST[randomNum]; return 'http://' + proxy.ip + ':' + proxy.port;
}

  对app.js代码做如下修改

/*
* 功能: 数据采集
* 创建人: Wilson
* 时间: 2015-07-29
*/
var request = require('request'),
cheerio = require('cheerio'),
URL_36KR = 'http://36kr.com/', //36氪
Proxy = require('./proxylist.js'); ... /* 数据请求 */
function dataRequest(dataUrl)
{
request({
url: dataUrl,
proxy: Proxy.GetProxy(),
method: 'GET'
}, function(err, res, body) {
...
} } ... dataCollectorStartup()
setInterval(dataCollectorStartup, 10000);

  这样就改造完成,加入代码,并且加了setInterval进行定间隔执行!

请求https

  上面示例中采集http请求,如果换成https呢?

  新建app2.js,代码如下

/*
* 功能: 请求HTTPS
* 创建人: Wilson
* 时间: 2015-07-29
*/
var request = require('request'),
URL_INTERFACELIFE = 'https://interfacelift.com/wallpaper/downloads/date/wide_16:10/'; /* 开启数据采集器 */
function dataCollectorStartup() {
dataRequest(URL_INTERFACELIFE);
} /* 数据请求 */
function dataRequest(dataUrl)
{
request({
url: dataUrl,
method: 'GET'
}, function(err, res, body) {
if (err) {
console.log(dataUrl)
console.error('[ERROR]Collection' + err);
return;
} console.info(body); });
} dataCollectorStartup();

  执行会发现返回body中什么也没有^_^!

  加入一些代码再看看

/*
* 功能: 请求HTTPS
* 创建人: Wilson
* 时间: 2015-07-29
*/
var request = require('request'),
URL_INTERFACELIFE = 'https://interfacelift.com/wallpaper/downloads/date/wide_16:10/'; /* 开启数据采集器 */ ... /* 数据请求 */
function dataRequest(dataUrl)
{
request({
url: dataUrl,
method: 'GET',
headers: {
'User-Agent': 'wilson'
}
}, function(err, res, body) {
if (err) {
console.log(dataUrl)
console.error('[ERROR]Collection' + err);
return;
} console.info(body); });
} ...

  再执行,你会发现body中返回请求的HTML!(结果就不放上来了,自已执行一下!)

  详细的请看:https://github.com/request/request#custom-http-headers  

写在之后

  request库我还是推荐API可以多看看,比如Forms部分我就在实际项目测试中用的比较多!

  比如做接口测试:

  1.提交两个参数(参数1:字符串  参数2:数字)

request.post({url:'接口URL',form: {参数一名称:'参数一值',参数二名称:参数二值},function(err,res,body){ 

            if(err)
{
return;
}
console.log(body);
});

  body就是接口返回

  2.提交一个字符串参数,提交一个文件参数(比如上传头像等)

var r = request.post('接口URL',function(err,res,body){
if(err)
{
return;
 }
 console.log(body);
});
var form = r.form();
form.append('参数一名称', '参数一值');
form.append('参数二名称', fs.createReadStream('1.jpg'), {filename: '1.jpg'});

  cheerio库真没什么好讲的,会jquery就行,它库的api基本都不用看!

此系列的源代码可到http://bijian1013.iteye.com/blog/2425085下载。

文章来源:https://www.cnblogs.com/zhongweiv/p/node_request_cheerio.html

Nodejs学习笔记(十一)—数据采集器示例(request和cheerio)的更多相关文章

  1. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  2. [转]Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    本文转自:https://www.cnblogs.com/zhongweiv/p/nodejs_koa2_webapp.html 目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装 ...

  3. Nodejs学习笔记(十五)—Node.js + Koa2 构建网站简单示例

    前言 前面一有写到一篇Node.js+Express构建网站简单示例:http://www.cnblogs.com/zhongweiv/p/nodejs_express_webapp.html 这篇还 ...

  4. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  5. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  6. Nodejs学习笔记(十六)—Pomelo介绍&入门

    前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...

  7. Nodejs学习笔记(六)—Node.js + Express 构建网站预备知识

    前言 前面经过五篇Node.js的学习,基本可以开始动手构建一个网站应用了,先用这一篇了解一些构建网站的知识! 主要是些基础的东西... 如何去创建路由规则.如何去提交表单并接收表单项的值.如何去给密 ...

  8. NodeJS学习笔记 进阶 (1)Nodejs进阶:服务端字符编解码&乱码处理(ok)

    个人总结:这篇文章主要讲解了Nodejs处理服务器乱码及编码的知识,读完这篇文章需要10分钟. 摘选自网络 写在前面 在web服务端开发中,字符的编解码几乎每天都要打交道.编解码一旦处理不当,就会出现 ...

  9. Nodejs学习笔记(四)——支持Mongodb

    前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...

  10. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

随机推荐

  1. Node.js最新Web技术栈(2015年5月)

    https://cnodejs.org/topic/55651bf07d4c64752effb4b1

  2. 【笔记】virtualbox+arch+kde5安装流水账

    正常安装就是RTFD就行了,不行辅助这几个链接也行: 我先把整个脚本[1]放这里: loadkeys us parted mkfs.ext4 /dev/sda1mkfs.ext4 /dev/sda3 ...

  3. PLSQL(PL/SQL)集成Team Foundation Server (TFS),实现数据库代码的版本管理

    PL/SQL是面向Oralcle数据库的集成开发环境,是众多Oracle数据库开发人员的主要工具.由于PL/SQL(百度百科)不仅是一种SQL语言,更是一种过程编程语言,在项目实施过程中,会积累大量除 ...

  4. ASP.NET开发常用简单实用的方法

    ASP.NET开发简单实用的方法 一.打印和导出 打印和导出EXCEL在目前ASP.NET开发中可以说是必要的,有时候针对不同数据难易程度下,用有效快速的方法是解决办法的有效途径之一. 1.打印 后台 ...

  5. 【 PLSQL Developer安装、tnsnames.ora配置 解答】

    使用plsql远程连接数据库需要安装plsql工具+ oracle的远程客户端 在不登录的状态打开plsql: 点击工具---首选项:指定oracle客户端的安装路径: C:\javaSoft\PLS ...

  6. python——排序

    从学校毕业出来后只知道冒泡排序,发现自己对排序的了解还是很浅显. 于是在网上搜索各种排序方法,以下是本人根据索搜出来的资料再结合自己理解作出的一些简单的阐述. 如果有不正确的地方欢迎大家指正.(共同学 ...

  7. asp.net 网站监控方案

    前言:监控web网站方法有很多种,这篇文章说一下对windows服务器 asp.net网站的监控 采用的方案,Powershell + Influxdb + Grafana 1.PowerShell ...

  8. 【C#进阶】委托那些事儿(二)

    二.传统的委托 接下来讲一讲方法参数.下面以“餐馆服务员为客户下单”[2]的事件作为描述.一般对事件的做法分3个部分: 1. 方法参数 EventArgs,一般用于传送数据.在本例场景中 public ...

  9. select * 和 select 所有字段写出来 ,速度对比!

    从很早时候,听老师说 select * from table  比 select a,b,c,d from table 要慢很多.3年来从未测试.  今天没事测一测, 不测不知道,一测吓一跳. 当然 ...

  10. OSLab课堂作业2

      日期:2019/3/23 内容: 实现内容 要求 mysys.c 实现函数mysys,用于执行一个系统命令. mysys的功能与系统函数system相同,要求用进程管理相关系统调用自己实现一遍 使 ...