网页新闻抓取(NodeJs.js使用NodeJs做网络爬虫RSS抓取新闻(组图))
优采云 发布时间: 2021-09-27 21:14网页新闻抓取(NodeJs.js使用NodeJs做网络爬虫RSS抓取新闻(组图))
Node.js是一个基于chrome JavaScript运行时的平台,用于轻松构建快速且易于扩展的网络应用程序。借助事件驱动和非阻塞I/O模型,Node.js变得轻量级和高效。它非常适合跨分布式设备运行的数据密集型实时应用程序·
有许多网站提供RSS服务,如百度、网易、新浪、husniff等。有许多基于Java、C++和PHP的RSS爬行网站。今天,让我们来谈谈nodejs抓取RSS信息
使用nodejs作为网络爬虫来捕获RSS新闻。每个站点都有不同的编码格式,如GBK、UTF-8、iso8859-1等,因此需要对其进行编码。对于中国人来说,UTF-8是最酷的。抓取多个站点,然后将它们保存到数据库中。充分利用JavaScript异步编程的特点,爬网速度超快
这个项目是为新闻Android客户端实现的。将来,我还会上传新闻客户端的源代码
此项目的源代码位于GitHub中:
环境要求:
Nodejs(必选),我的版本是0.10.24
Mongodb(可选)或其他数据库,如mysql
编程工具:webstrom
步骤1:创建一个新的nodejs项目。我通常创建一个express web项目。步骤2:在package.json文件中添加依赖项
"dependencies": {
"express": "3.4.8",
"ejs": "*",
"feedparser":"0.16.6",
"request":"2.33.0",
"iconv":"2.0.7",
"mongoose":"3.8.7",
"mongodb":"*"
}
执行以下代码将相关文件导入模块中的项目节点:
npm install -d
步骤3:
完成基本准备后,就可以开始编写代码了。RSS捕获主要依赖于feedparser库。GitHub地址:
首先配置要捕获的站点信息
创建一个rssitejson文件
{
"channel":[
{
"from":"baidu",
"name":"civilnews",
"work":false, //false 则不抓取
"title":"百度国内最新新闻",
"link":"http://news.baidu.com/n?cmd=4&class=civilnews&tn=rss",
"typeId":1
},{
"from":"netEase",
"name":"rss_gn",
"title":"网易最新新闻",
"link":"http://news.163.com/special/00011K6L/rss_gn.xml",
"typeId":2
}
]
}
我想抓住这两个网站。通道的值是一个对象数组。如果您需要多个站点,只需直接添加它们
介绍相关软件包
var request = require('request')
, FeedParser = require('feedparser')
, rssSite = require('../config/rssSite.json')
, Iconv = require('iconv').Iconv;
您需要遍历新配置的通道以找到所需的URL地址
var channels = rssSite.channel;
channels.forEach(function(e,i){
if(e.work != false){
console.log("begin:"+ e.title);
fetch(e.link,e.typeId);
}
});
工作为false的站点不会被爬网。就是黑名单。TypeID标识新闻属于哪一列、社会、金融或其他
关键是fetch函数,它是捕获和分析的地方。在我解释之前,我会发布代码
function fetch(feed,typeId) {
var posts;
// Define our streams
var req = request(feed, {timeout: 10000, pool: false});
req.setMaxListeners(50);
// Some feeds do not response without user-agent and accept headers.
req.setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36')
.setHeader('accept', 'text/html,application/xhtml+xml');
var feedparser = new FeedParser();
// Define our handlers
req.on('error', done);
req.on('response', function(res) {
var stream = this
, iconv
, charset;
posts = new Array();
if (res.statusCode != 200) return this.emit('error', new Error('Bad status code'));
charset = getParams(res.headers['content-type'] || '').charset;
if (!iconv && charset && !/utf-*8/i.test(charset)) {
try {
iconv = new Iconv(charset, 'utf-8');
iconv.on('error', done);
stream = this.pipe(iconv);
} catch(err) {
this.emit('error', err);
}
}
stream.pipe(feedparser);
});
feedparser.on('error', done);
feedparser.on('end', function(err){
// postService.savePost(posts); //存到数据库
});
feedparser.on('readable', function() {
var post;
while (post = this.read()) {
posts.push(transToPost(post));//保存到对象数组
}
});
function transToPost(post){
var mPost = new Post({
title : post.title,
link : post.link,
description : post.description,
pubDate : post.pubDate,
source : post.source,
author : post.author,
typeId : typeId
});
return mPost;
}
}
1、关键功能:请求(URL,[选项]);这是一个可以发送HTTP请求的函数。地址:
var req = request(feed, {timeout: 10000, pool: false});
Req需要侦听多个状态响应和错误。发送请求后,将收到响应。收到响应后,将拼接接收到的数据。在拼接之前,需要进行编码转换。非utf8代码转换为UTF8.,此处使用库iconv。地址:
res.headers['content-type'].charset;
通过这种方式,您可以获得所获取站点的编码格式
拼接前需要进行代码转换。当然,这里使用了一种巧妙的方法,管道
然后把它转换成我无法操作的对象。此时,需要启动feedparser
var feedparser = new FeedParser();
Feedparse还侦听多个状态:可读、结束、错误
readable的回调方法将一次读取一条记录。每次读取一条记录时,我都会将其保存到数组对象中
读取所有数据后,调用end的回调函数。此时,站点捕获已完成。或多个站点
步骤4:保存到数据库
所有数据都存储在POST的数组对象中。你无论如何都可以寄。保存到mongodb只需几行代码。这里使用猫鼬图书馆
当然,mongodb库也是必要的。猫鼬与BaseDao相似。操作mongodb数据库非常方便
首先建立模式:
var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
title:String,
link :String,
description :String,
pubDate :String,
source :String,
author :String,
typeId : Number
});
module.exports = PostSchema;
重新建立模型:
var mongoose = require('mongoose');
var PostSchema = require('../schemas/PostSchema');
var Post = mongoose.model('Post',PostSchema);
module.exports = Post;
好的,您可以将其保存到数据库中。mongodb似乎无法批量插入。我在这里骑自行车。如果标题不存在,请插入它,否则将出现重复新闻
<p>var Post = require('../model/Post');
function savePost(posts){
for(var i = 0 ;i