Node.js抓取网页
前几天四六级成绩出来(然而我没考),用Node.js做了一个模拟表单提交并抓取数据的Web
总结一下用到的知识,简单的网页抓取大概就是这个流程了
发送Get或Post请求
表单提交,首先弄到原网页提交的地址,然后引入http或https模块
也可以下载使用request模块。
这边以get为例
var http = require('http');
//设置请求参数,包括headers
var options = {
url: 'www.chsi.com.cn',
encoding: null,
host: 'www.chsi.com.cn',
path: '/cet/query?' + querystring,
method: 'GET',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'zh-CN,zh;q=0.8',
'Connection': 'keep-alive',
'Cookie': 'JSESSIONID=8D79F004CB79FC5352F123F76CF4D853; __utmt=1; __utma=65168252.1576213452.1471513579.1471575867.1471575870.3; __utmb=65168252.5.10.1471575870; __utmc=65168252; __utmz=65168252.1471575870.3.3.utmcsr=baidu|utmccn=(organic)|utmcmd=organic|utmctr=%E5%AD%A6%E4%BF%A1%E7%BD%91',
'Host': 'www.chsi.com.cn',
'Referer': 'http://www.chsi.com.cn/cet/',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
};
var req = http.request(options, function(res){
res.on('data', function(data){
//处理data事件,当接收到数据时触发
}).on('end', function(){
//处理读取完所有数据的事件
}).on('error', function(err){
//处理错误时的事件
console.log(err);
});
});
//发送请求
req.end();
如果是post请求,需要在req.end()之前用req.write(content)写入请求参数
Transfer-Encoding:chunked?
有时候服务器的response header会带有一个Transfer-Encoding,如果是chunked,说明服务器是分段传输数据的
这种情况下,会触发多次res的data事件,因此可以先定义一个变量,然后在data事件处理函数中将接收到的数据拼接起来
var req = http.request(options, function(res){
var data = '';
res.on('data', function(chunk){
//处理data事件,当接收到数据时触发
data += chunk;
}).on('end', function(){
//处理读取完所有数据的事件
}).on('error', function(err){
//处理错误时的事件
console.log(err);
});
});
//发送请求
req.end();
使用zlib库解压gzip压缩过的html
现在很多网站在进行数据传输时都会先用gzip或deflate压缩以减小传输数据的体积,这样,我们请求到的数据就是压缩过的数据,无法正常解析,因此需要先解压
Node.js带有一个zlib库可以用来解压gzip格式的数据
我们可以利用Node.js的管道流机制,将接收到的数据先通过pipe()交给zlib处理,然后再进行我们自己的处理
var zlib = require('zlib');
var req = http.request(options, function(res){
var gunzip = zlib.createGunzip();
res.pipe(gunzip); //通过pipe()将数据交给gunzip
var data = '';
//事件处理,res.on改为gunzip.on
gunzip.on('data', function(chunk){
//处理data事件,当接收到数据时触发
data += chunk;
}).on('end', function(){
//处理读取完所有数据的事件
}).on('error', function(err){
//处理错误时的事件
console.log(err);
});
});
//发送请求
req.end();
压缩html字符串(去除换行符)
接收到的data如果不是json格式而是html,就需要进一步处理
但是在html中有各种换行符,不方便进行正则匹配,因此先把换行符去掉
htmlstring = htmlstring.replace(/[\r\n]/g, '');
用正则表达式提取有用的信息
去除了烦人的换行符后,就可以愉快地用正则来获取我们需要的信息啦
什么?你不会用正则?
学啊,相信你肯定搜到过这个 正则表达式30分钟入门教程 ,需要的时候看一看。
大致的匹配流程是这样的:
var reg = new RegExp(''); //参数为正则的pattern
var arr = [];
arr = htmlstring.match(reg); //显然match()方法返回的是匹配结果的数组,如果没有结果则返回null
这里贴个MDN上的文档,提高提高姿势水平
* RegExp - JavaScript | MDN
* String.prototype.match() - JavaScript | MDN
解析html(可选)
如果你不想用正则对html数据进行处理,没关系,还可以选择对html数据构造DOM树,然后通过各种选择器来获取你需要的数据
像是node-jquery、node-htmlparser之类的,具体的做法问Google吧,这边贴上一篇文章供参考 NodeJS 中寻找可用的 HTMLParser
我也没用过,就不多说了。
参考
Node.js抓取网页的更多相关文章
- node.js 抓取网页数据
var $ = require('jquery'); var request = require('request'); request({ url: 'http:\\www.baidu.com',/ ...
- Node.js 抓取电影天堂新上电影节目单及ftp链接
代码地址如下:http://www.demodashi.com/demo/12368.html 1 概述 本实例主要使用Node.js去抓取电影的节目单,方便大家使用下载. 2 node packag ...
- 使用node.js抓取有路网图书信息(原创)
之前写过使用python抓取有路网图书信息,见http://www.cnblogs.com/dyf6372/p/3529703.html. 最近想学习一下Node.js,所以想试试手,比较一下http ...
- node.js抓取数据(fake小爬虫)
在node.js中,有了 cheerio 模块.request 模块,抓取特定URL页面的数据已经非常方便. 一个简单的就如下 var request = require('request'); va ...
- node.js 抓取
http://blog.csdn.net/youyudehexie/article/details/11910465 http://www.tuicool.com/articles/z2YbAr ht ...
- node.js抓取网上图片保存到本地
用到两个模块,http和fs var http = require("http");var fs = require("fs"); var server = h ...
- Java抓取网页数据(原网页+Javascript返回数据)
有时候由于种种原因,我们需要采集某个网站的数据,但由于不同网站对数据的显示方式略有不同! 本文就用Java给大家演示如何抓取网站的数据:(1)抓取原网页数据:(2)抓取网页Javascript返回的数 ...
- python抓取网页例子
python抓取网页例子 最近在学习python,刚刚完成了一个网页抓取的例子,通过python抓取全世界所有的学校以及学院的数据,并存为xml文件.数据源是人人网. 因为刚学习python,写的代码 ...
- python分布式抓取网页
呵呵,前两节好像和python没多大关系..这节完全是贴代码, 这是我第一次写python,很多地方比较乱,主要就看看逻辑流程吧. 对于编码格式确实搞得我头大..取下来页面不知道是什么编码,所以先找c ...
随机推荐
- CSS3中的px,em,rem,vh,vw辨析
1.px:像素,精确显示 2.em:继承父类字体的大小,相当于"倍",如:浏览器默认字体大小为16px=1em,始终按照div继承来的字体大小显示,进场用于移动端 em换算工具:h ...
- [MySQL] MySQL存储过程常用的函数
一.字符串类 CHARSET(str) //返回字串字符集 CONCAT (string2 [,... ]) //连接字串 INSTR (string ,substring ) //返回substr ...
- markdownTest
MARKDOWNTEST 11111111111111 有一种神奇的语言,它比html还简单,它巧妙地将内容与格式整合在一起--它就是Markdown 有一种神奇的语言,它比html还简单,它巧妙地将 ...
- 正确解读free -m
如下显示free是显示的当前内存的使用,-m的意思是M字节来显示内容.我们来一起看看. $ free -m total used free shared buffers cachedMem: 1002 ...
- url带#号,微信授权,微信分享那些坑
微信授权的方法是,在项目里面配置拦截器(此处可以参考各个框架的拦截器)没有拦截器也可以,反正意思就是跳转到项目里的时候判断微信环境 如果是微信环境, 判断微信环境的方法是 var ua = windo ...
- Css格式与布局
一.位置 1.绝对定位 position:absolute:绝对定位. 绝对位置的意思就是相对于浏览器边框的位置,回归到它应有的位置.也就是说,一个div使用绝对定位后是在浏览器边框的最左上角位置.而 ...
- 分享一个常用Adb命令
分享一个常用Adb命令 首先 首先感谢@xuxu的常用adb命令,收益良多,但是已经不能满足于我,所以补充了下. 再者 好久没发帖了,最近论坛老司机们都在讨论/总结,我就用这个干货回报吧. 最后 基于 ...
- kettle系列-6.kettle实现多字段字典快速翻译
在数据清洗转换中,常见的字典翻译,如性别在原表中是1(男).2(女)等,类似还有很多较大的字典需要翻译,若同一个表中有很多个字典需要翻译,采用[数据库查询]方式翻译的话效率就会相当低下. 这里采用ja ...
- ShareSDK分享失败的原因
关于分享估计很多都用的是ShareSDK的社会化分享,简单方便,支持的种类很多,但是一般的话都还是QQ,微信,新浪微博,腾讯微博为主. 最近需要导入一个分享的模块,失败了几次之后最终成功,分享给大家, ...
- 给hadoop新手的一封信:Hadoop入门自学及对就业的帮助
学习指南,刚接触这个确实有点懵逼,感觉还有很多东西要学要看,自己要逐渐构造成一个框架的体系. 附上一个学习博客地址: http://www.cnblogs.com/mephisto/p/4835386 ...