这篇文章是我学习node-feedparser的时候所写的,前半部分是翻译了node-feedparser在github上的原文(英语不好,如果翻译有误,还请见谅。),当中也夹杂了一些自己解释;后半部分的实战是我结合 compressed.js
,同时自己在实际运用中的小结,现在拿出来和大家分享,希望大家给予指正。
文章信息
- 时间 / 2017年3月9日
- 版本号
- Node.js: v6.10.0
- node-feedparser: v2.1.0
- request: v2.79.0
- iconv-lite: v0.4.15
- 项目地址 / https://github.com/danmactough/node-feedparser
目录
- Feedparser 基于Node.js的RSS,Atom,RDF强劲解析器
- 如何安装
- 用法
- feedparser可选参数
- 例子
- API
- feedparser解析后能得到什么?
- meta属性列表
- article属性列表
- 贡献
License
实战
- 处理数据
- 取得数据
- 编码问题
- 错误捕捉
Feedparser 基于Node.js的RSS,Atom,RDF强劲解析器
Feedparser是一个基于基于Node.js的强劲解析器,可以解析包括RSS,Atom和RDF信息
它有一对特性是你在其他的Feed解析器中不常见的:
它可以解析一些相对URL链接(例如Tim Bray’s “ongoing”这个Feed)
它可以正确地解析一些XML命名空间(包含那些非常规的Feed——用主要的一些Feed元素来定义的非常规命名空间)
说明:对第二条的理解是,通常Feed的XML命名是固定的一些标签,但是Feedparser同样可以对一些非常规的XML进行解析,这就是强大之处。
如何安装
用法
这个例子能简要地示范feedparser的基本概念:
请注意在学习基本的示范的同时,也要学习简化的范例compressed.js文件,这样也能够让你更全面地开展工作。
feedparser可选参数
normalize
:设置false
让Feedparser的默认值失效。无论这个Feed的形式,这个参数都能将其解析成一个包含RSS2.0格式,正确属性的对象。序列化后的形式如以下所示(只进入第一层):
addmeta
:设置false
让Feedparser的默认值失效。让每一个Feed的article信息都加入Meta信息。个人建议可以设置为true,一般来说,每个Feed的Meta信息都是唯一的,而article信息不同,只要第一次获取Meta后,就可以只需要article信息。feedurl
:Feed的URL地址。FeedParser能非常优秀地处理相对url,但是一些Feed在使用相对url时,并不声明xml:base
信息。尽管feedparser非常有效,但是在我们处理feed和尝试着处理这些相对url之前,我们仍然不能知道feed的url。如果我们发现了feed的url,我们将会返回并处理那些我们已经得到的相对url,但这将会消耗一段时间(并非很长)。如果你想要确信我们不对相对url进行预处理(或者feedparser无法处理相对url),你应该设置feedurl
选项,否则,你就当没看见过它吧~resume_saxerror
:设置false
让Feedparser的默认值失效。这个选项能够抛出error
中的SAXError
错误,并自动进行后续的解析。在我的测试中,SAXErrors
并不常错误,所以开启这个选项通常对你很有帮助。如果你想要完全掌握和处理错误,并在任意点中止解析feed的话,可以尝试用这个选项。
例子
在这里查看例子 examples
。
API
转换 Stream
Feedparser是一个stream转换器(关于stream你可以在nodejs官网阅读),从XML文件转换为Javascript的objects对象。
每一个可读的区块都是一个对象,这个对象代表feed中的article信息。
发出的项目
meta
- 被解析后,称作feed的meta
error
- 任何时候Feedparser发出的错误(包括SAXError, Feedparser error等)
feedparser解析后能得到什么?
Feedparser对每一个Feed都会解析出 meta
和一个或更多的 articles
。
不论Feed的形式如何, meta
和每一个 article
都包含一个RSS2.0规范同时加上规范化后的属性的信息流。举个例子,一个Atom feed会有一个 meta.description
属性,但是同样会有一个 meta['atom:subtitle']
属性。
这个规范化后的属性是用于向用户提供一个规范的接口——当你不知道feed的形式,或者搞不清不同feed形式之间的差异时,用这个接口就可以方便获取feed信息。不过当你需要原始信息的时候会依然会保留给你使用。此外,Feedparser还提供了一些大众化的命名空间扩展,例如 itunes
, media
, feedburner
和 pheedo
这些扩展。举例:如果一个feed的article同时包含了 itunes:image
或 media:thumbnail
,那么这两个的url地址都会保存到article的 image.url
属性中。
所有的属性都会进行初始化,设置为 null
(空数组或者空对象都会有恰当的属性)。这个能够节省你很多时间来检查属性是否为 undefined
,例如,当你使用jade模板的时候。
除此之外,所有的属性(包含命名空间)都使用小写字母(”xmlUrl” and
“pubDate”仍然提供向下兼容)。“好用”取代了“原生”——衷心希望你能不必为骆驼拼写法而烦恼。
如果你设置normalize为true,那么 meta
和 article
的 title
和 description
属性都会将HTML标签剥离。如果你需要这些HTML元素,你可以从 meta['atom:subtitle']['#']
这个属性取得。
meta属性列表
- title
- description
- link (网站链接)
- xmlurl
- date (最近的日期)
- pubdate (原始出版日期)
- author
- language
- image (一个对象,包含
url
和title
属性) - favicon (favicon的链接——只提供给Atom feeds)
- copyright
- generator
- categories (一个字符串数组)
article属性列表
- title
- description (通常是完整的标题内容)
- summary (通常是文章摘录)
- link
- origlink
- permalink
- date
- pubdate
- author
- guid
- comments
- image
- categories
- source
- enclosures
- meta
贡献
在这里查看所有代码 -> contributors。
License
(The MIT License)
实战
处理数据
需要注意的是你无法通过return将上述的数据从函数中取出,也无法通过在外定义变量,在内赋值取出。因为这里用到了异步编程的事件监听,所有的动作都是异步操作,如果通过上述两个办法取出的值都是undefined。那么如何取出这些数据?这里有两个办法:
取得数据
因为feedparser使用的是异步编程的办法,所以无法通过常规方法取出值,不过仍然有以下两种办法:
- 直接在函数中进行操作
- 使用Promise封装
编码问题
在抓取非英文网页时,总会遇到编码问题,中文也不例外。比如新浪新闻的编码是”utf-8”,但是腾讯新闻的编码是”gb3212”。feedparser虽然强大,但不负责解决这些问题,这个时候需要我们引入 iconv-lite
,来解决编码问题。
因为 request
和 feedparser
之间的通讯是通过stream流的,而 iconv-lite
正好又有对于Stream流的API接口,所以直接调用即可。如果感兴趣或者有需要的同学还可以去查看 iconv-lite
的官方文档查看其它的方法。
错误捕捉
在整个抓取Feed的过程中,会遇到很多的错误,如何处理这些错误?这里借鉴一下官方文档所提到的 compressed.js
中的方法,它将所有的错误处理写成一个函数,然后在每次事件监听的地方,调用处理错误函数即可完成。
原文:大专栏 feedparser学习与实战——基于Node.js的Feed解析器