简单介绍Python中的RSS处理


Posted in Python onApril 13, 2015

RSS 是一个可用多种扩展来表示的缩写:“RDF 站点摘要(RDF Site Summary)”、“真正简单的辛迪加(Really Simple Syndication)”、“丰富站点摘要(Rich Site Summary)”,也许还能用其他扩展来表示。在如此混乱的名称背后,您会发现和这样一个平凡的技术领域相关的故事多得令人吃惊。RSS 是用于分发 Web 站点上的内容的摘要的一种简单的 XML 格式。它能够用于共享各种各样的信息,包括(但不是 仅限于)简讯、Web 站点更新、事件日历、软件更新、特色内容集合和基于 Web 进行拍卖的商品。

RSS 是 Netscape 在 1999 年创建的,它允许将许多信息源中的内容聚集到 Netcenter 门户网站中(这个门户网站现在已经不存在了)。UserLand 社区中的 Web 狂热爱好者们成为了 RSS 早期的支持者,RSS 很快就成为了一种非常流行的格式。这种流行使得人们很难对 RSS 进行改进从而使它能用于更多的地方。这种限制导致了 RSS 的发展出现了分歧。其中一个组选择了一种基于 RDF 的方式,目的在于利用大量的 RDF 工具和模块,而另一个组则选择了一种更加紧缩的方式。前者被称之为 RSS 1.0,而后者则被称之为 RSS 0.91。就在上个月由于 RSS 非 RDF 变体的一个新版本的出现使得两者之间的竞争进一步加剧,这一新版本被它的创造者称之为“RSS 2.0”。

RSS 0.91 和 1.0 非常流行,并且许许多多的门户网站和 Web 日志都使用它们。事实上,blogging 社区是 RSS 的主要用户,而 RSS 就是某些现有的用于 XML 交换的网络令人印象深刻的理由。这些网络已在有机地增长,并且真正地成为现有的最成功的 XML 服务的网络。RSS 成为一种 XML 服务是因为它被通过网际协议交换 XML 信息(绝大多数的 RSS 交换是 RSS 文档的简单 HTTP GET)。在本文中,我们介绍的不过是许多可以与 RSS 一起工作的 Python 工具中的少数几个。我们不提供针对 RSS 的技术上的介绍,因为您可以在其他许多的文章中获得这些内容。(请参阅 参考资料)。我们推荐您首先简单地熟悉一下 RSS 知识,并且能了解 XML。您不需要去了解 RDF。

[ 由于 RSS 使用了 XML 描述而没有使用 WSDL,所以我们将 RSS 作为一个“XML 服务”而不是一个“Web 服务”对待。- 编者按 ]

RSS.py

Mark Nottingham 编写的 RSS.py 是用于 RSS 处理的一个 Python 库。它非常完善并且编写的很好。它需要 Python 2.2 和 PyXML 0.7.1。它的安装是非常简单;您只需从 Mark 的主页中下载 Python 文件并将它复制到您的 PYTHONPATH 中的某处。

大多数 RSS.py 的用户本身只需要关心它所提供的两个类: CollectionChannel 和 TrackingChannel 。后者似乎是这两个类中更有用的一个。 TrackingChannel 是一个包含以每一项的关键字为索引的所有的 RSS 数据的数据结构。 CollectionChannel 是一个类似的数据结构,但它的结构更像 RSS 文档本身,它的顶层通道信息使用 URL 表示的散列值指向项细节。您很可能会使用 RSS.ns 结构中的实用程序名称空间声明。 清单 1是一个简单的脚本,它将下载并解析用于 Python 新闻的 RSS 供给,并以一个简单的清单形式打印来自各项的所有信息。

清单 1:使用 RSS.py 的一个简单练习

 

from RSS import ns, CollectionChannel, TrackingChannel
#Create a tracking channel, which is a data structure that
#Indexes RSS data by item URL
tc = TrackingChannel()
#Returns the RSSParser instance used, which can usually be ignored
tc.parse("http://www.python.org/channews.rdf")
RSS10_TITLE = (ns.rss10, 'title')
RSS10_DESC = (ns.rss10, 'description')
#You can also use tc.keys()
items = tc.listItems()
for item in items:
  #Each item is a (url, order_index) tuple
  url = item[0]
  print "RSS Item:", url
  #Get all the data for the item as a Python dictionary
  item_data = tc.getItem(item)
  print "Title:", item_data.get(RSS10_TITLE, "(none)")
  print "Description:", item_data.get(RSS10_DESC, "(none)")

我们从创建一个 TrackingChannel 实例开始,并且将从 http://www.python.org/channews.rdf 上的 RSS 供给解析得到的数据填入其中。RSS.py 使用元组作为 RSS 数据的属性名称。对于那些不习惯 XML 处理技术的人来说,这种方式看上去也许不太寻常,但它对于精确了解原始的 RSS 文件中的内容的确是一种很有效的方式。因此,一个 RSS 0.91 title 元素被认为不同于一个 RSS 1.0 中的同名元素。应用程序有足够的数据来忽略这个差异,如果您愿意,可以通过忽略每个元组的名称空间的部分来忽略这个差异;但基本的 API 是与初始 RSS 文件的语法相结合的,所以这个信息没有丢失。在代码中,我们使用这个属性数据来聚集用于显示的新闻供给中的所有项。请注意,我们很仔细地不去假定任何特殊的项可能会有什么属性。我们使用如下代码所示的安全的形式来检索属性。

print "Title:", item_data.get(RSS10_TITLE, "(none)")

如果没有找到该属性则它会提供一个缺省值,而不是这个示例。

  

print "Title:", item_data[RSS10_TITLE]

由于您不可能会知道 RSS 供给中所使用的是什么元素,因此这样的谨慎是有必要的。 清单 2显示了 清单 1的输出。

清单 2:清单 1 的输出

$ python listing1.py 
RSS Item: http://www.python.org/2.2.2/
Title: Python 2.2.2b1
Description: (none)
RSS Item: http://sf.net/projects/spambayes/
Title: spambayes project
Description: (none)
RSS Item: http://www.mems-exchange.org/software/scgi/
Title: scgi 0.5
Description: (none)
RSS Item: http://roundup.sourceforge.net/
Title: Roundup 0.4.4
Description: (none)
RSS Item: http://www.pygame.org/
Title: Pygame 1.5.3
Description: (none)
RSS Item: http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/
Title: Pyrex 0.4.4.1
Description: (none)
RSS Item: http://www.tundraware.com/Software/hb/
Title: hb 1.88
Description: (none)
RSS Item: http://www.tundraware.com/Software/abck/
Title: abck 2.2
Description: (none)
RSS Item: http://www.terra.es/personal7/inigoserna/lfm/
Title: lfm 0.9
Description: (none)
RSS Item: http://www.tundraware.com/Software/waccess/
Title: waccess 2.0
Description: (none)
RSS Item: http://www.krause-software.de/jinsitu/
Title: JinSitu 0.3
Description: (none)
RSS Item: http://www.alobbs.com/pykyra/
Title: PyKyra 0.1.0
Description: (none)
RSS Item: http://www.havenrock.com/developer/treewidgets/index.html
Title: TreeWidgets 1.0a1
Description: (none)
RSS Item: http://civil.sf.net/
Title: Civil 0.80
Description: (none)
RSS Item: http://www.stackless.com/
Title: Stackless Python Beta
Description: (none)

当然,你可能会遇到稍微有些不同的输出,这是因为在您对它进行试验时新闻项可能已经更改了。RSS.py 通道对象也提供方法来添加并修改 RSS 信息。您可以使用 output() 方法将结果写回 RSS 1.0 格式。通过将在 清单 1 中解析的信息写回去来对它进行试验。在交互式模式下通过运行 python -i listing1.py 来启动脚本。在产生的 Python 提示符下,运行以下示例。

>>> result = tc.output(items)
>>> print result

结果是一个打印输出的 RSS 1.0 文档。为了它能工作您必须有 RSS.py,版本 0.42 或者更高的版本。较早版本中的 output() 方法中有一个错误。

rssparser.py

Mark Pilgrim 为 RSS 文件解析提供了另一个模块。它并不提供 RSS.py 所提供的所有的功能部件和选项,但它却提供了一个非常自由的解析器,它能很好的处理 RSS 世界中所有令人混乱的差异。以下摘自 rssparser.py 页面:

    如您所见,大多数 RSS 供给都很糟糕。无效的字符、未转义的 & 符号(Blogger 供给)、无效的实体(Radio 供给)和未转义以及无效的 HTML(通常为注册中心所提供的)。或者只是 RSS 0.9x 元素和 RSS 1.0 元素的一个笼统的混合(可移动类型供给(Movable Type feeds))。

    还有许多太前沿的供给,就象 Aaron 的 feed。他将一个摘录放入描述元素中而将完整的文本放入 content:encoded 元素中(象 CDATA)。这是一个有效的 RSS 1.0,但没有人回真正使用它(除了 Aaron),几乎没有新闻聚集器支持它,并且许多解析器还排斥它。其他解析器被 RSS 0.94 中的新元素(guid)所困惑(请参阅 Dave Winer 的供给作为一个示例)。还有 Jon Udell 的供给,其中还有他才从创作中挑选出来的 fullitem 元素。

XML 和 Web 服务会增加互操作性几乎已成定局,所以这样考虑其实很可笑。无论如何,设计 rssparser.py 目的就是要处理所有这些荒唐的情况。

安装 rssparser.py 也十分简单。请您下载 Python 文件(参阅参考资料),将“rssparser.py.txt”重命名为 “rssparser.py”,并将它复制到您的 PYTHONPATH 中。我同样建议您取得可选的 timeoutsocket 模块,它可以改进 Python 中的套接字操作的超时行为,这样有助于取得 RSS feeds 而不必为了防止错误就停止应用程序线程。

清单 3是一个等同于 清单 1的脚本,但它使用了 rssparser.py,而不是 RSS.py。

清单 3:使用一个简单的 rssparser.py 练习

 

import rssparser
#Parse the data, returns a tuple: (data for channels, data for items)
channel, items = rssparser.parse("http://www.python.org/channews.rdf")
for item in items:
  #Each item is a dictionary mapping properties to values
  print "RSS Item:", item.get('link', "(none)")
  print "Title:", item.get('title', "(none)")
  print "Description:", item.get('description', "(none)")

如您所见,这段代码非常简单。RSS.py 和 rssparser.py 不能互相取代在很大程度上是因为前者有更多的功能部件,并且维护着 RSS 供给中更多的语法信息。后者更简单,并且是一个容错能力更强的解析器(RSS.py 解析器只能接受格式良好的 XML)。

它的输出应该与 清单 2中的输出相同。

Python 相关文章推荐
python网络编程学习笔记(三):socket网络服务器
Jun 09 Python
python使用心得之获得github代码库列表
Jun 25 Python
python中的装饰器详解
Apr 13 Python
Python实现计算文件夹下.h和.cpp文件的总行数
Apr 23 Python
Python实现程序的单一实例用法分析
Jun 03 Python
Ruby元编程基础学习笔记整理
Jul 02 Python
python与php实现分割文件代码
Mar 06 Python
使用Python写一个贪吃蛇游戏实例代码
Aug 21 Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
Aug 12 Python
Python批量启动多线程代码实例
Feb 18 Python
python实现udp聊天窗口
Mar 31 Python
python 多线程中join()的作用
Oct 29 Python
Python2.x和3.x下maketrans与translate函数使用上的不同
Apr 13 #Python
使用Pyrex来扩展和加速Python程序的教程
Apr 13 #Python
在Python中使用itertools模块中的组合函数的教程
Apr 13 #Python
Python中用Spark模块的使用教程
Apr 13 #Python
简单理解Python中基于生成器的状态机
Apr 13 #Python
Python中的高级函数map/reduce使用实例
Apr 13 #Python
Python遍历目录的4种方法实例介绍
Apr 13 #Python
You might like
检测png图片是否完整的php代码
2010/09/06 PHP
ajax取消挂起请求的处理方法
2013/03/18 PHP
如何阻止网站被恶意反向代理访问(防网站镜像)
2014/03/18 PHP
Codeigniter控制器controller继承问题实例分析
2016/01/19 PHP
解决在Laravel 中处理OPTIONS请求的问题
2019/10/11 PHP
Ajax,UTF-8还是GB2312 eval 还是execScript
2008/11/13 Javascript
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
jQuery学习笔记之Helloworld
2010/12/22 Javascript
使用GruntJS构建Web程序之构建篇
2014/06/04 Javascript
JS+CSS实现简易的滑动门效果代码
2015/09/24 Javascript
基于Vuejs实现购物车功能
2016/08/02 Javascript
jQuery插件EasyUI设置datagrid的checkbox为禁用状态的方法
2016/08/05 Javascript
Bootstrap CSS组件之面包屑导航(breadcrumb)
2016/12/17 Javascript
JS中去掉array中重复元素的方法
2017/05/26 Javascript
jQuery实现鼠标点击处心形漂浮的炫酷效果示例
2018/04/12 jQuery
iview实现select tree树形下拉框的示例代码
2018/12/21 Javascript
Vue 实现html中根据类型显示内容
2019/10/28 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 战前探营!
2014/05/21 DOTA
[01:02:10]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第一局
2016/02/26 DOTA
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
Python中使用PIL库实现图片高斯模糊实例
2015/02/08 Python
Python中取整的几种方法小结
2017/01/06 Python
Python中模块string.py详解
2017/03/12 Python
Python 查看文件的读写权限方法
2018/01/23 Python
Python图像阈值化处理及算法比对实例解析
2020/06/19 Python
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
Python的两道面试题
2013/06/29 面试题
打架检讨书500字
2014/01/29 职场文书
酒店大堂副理的职责范文
2014/02/13 职场文书
竞选演讲稿范文大全
2014/05/12 职场文书
2014银行领导班子群众路线对照检查材料思想汇报
2014/09/17 职场文书
餐厅如何利用“营销策略”扭转亏本局面
2019/10/15 职场文书
年会邀请函的格式及范文五篇
2019/11/02 职场文书
Nginx源码编译安装过程记录
2021/11/17 Servers
sqlserver连接错误之SQL评估期已过的问题解决
2022/03/23 SQL Server