RSS是什么
RSS是一种用于新闻和web站点内容聚合的格式,包括主要的新闻站点如《连线》杂志(Wired),基于新闻的社区站点如Slashdot,以及个人博客(blog).但是它并不只用于新闻。几乎任何可以分割成独立项目的事物都能通过RSS聚合:维基(wiki)页面的最新更新,CVS的更新日志,甚至是一本书的历史版本。只要项目的信息是用RSS格式写的,一个RSS程序就能检查feed获取更新并且用合适的途径显示更新。
RSS程序也被称作新闻聚合器,在博客社区很流行。很多博客都支持RSS。一个新闻聚合器可以通过检查站点RSS feeds并显示更新的项目来帮助你及时获得你喜欢的博客站点的更新。
版本大纲
事实上RSS包括两种完全不同的格式。最初的RSS格式-0.90版,是由网景公司(Netscape)定义的一种通过标题链接进入新闻站点主页面的格式。相对于它要达到的目标来说,0.90版被认为过于复杂;因此,一个简单的版本,0.91版被提上议程,但随后网景公司对该计划不再感兴趣而放弃。但是,另一家公司,UserLand Software,重拾0.91版,用于该公司的博客产品和其他基于web编辑的软件。
同时,一个非盈利的第三方组织基于0.90版定义了一种新的格式。这种格式基于RDF,被称为1.0版。但是,Userland公司没有参与该新格式的制定,同时,作为一个简化0.90版的倡导者,他并不乐于看见1.0版的发布。因此,UserLand不仅不接受1.0版,反而继续制定了0.9x版,包括0.92,0.93,0.94,最终2.0版。
真是混乱啊!
那我该使用什么版本呢?
RSS共有7种不同格式。作为一个RSS程序的解码器,你需要支持所有的格式。但是作为内容的发布者来说,应该使用何种格式呢?
RSS是怎么样的呢?
如果你想写个程序来读RSS feeds,这样你可以在自己的站点上发布标题,生成自己的新闻聚合器,或者任何东西。那么RSS feed是怎么样的呢?这依赖于
你所讨论的是什么版本的RSS。下面给个RSS 0.91的feed的例子:
<rss version="0.91">
<channel>
<title>XML.com</title>
<link>http://www.xml.com/</link>
<description>XML.com features a rich mix of information and services for the XML community.</description>
<language>en-us</language>
<item>
<title>Normalizing XML, Part 2</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html</link>
<description>In this second and final look at applying relational normalization techniques to W 3C XML Schema data modeling, Will Provost discusses when not to normalize, the scope of uniqueness and the fourth and fifth normal forms.</description>
</item>
<item>
<title>The .NET Schema Object Model</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /som.html</link>
<description>Priya Lakshminarayanan describes in detail the use of the .NET Schema Object Model for programmatic manipulation of W 3C XML Schemas.</description>
</item>
<item>
<title>SVG's Past and Promising Future</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /svg.html</link>
<description>In this month's SVG column, Antoine Quint looks back at SVG's journey through 2002 and looks forward to2003.</description>
</item>
</channel>
</rss>
很简单,不是吗?一个feed由一个频道(channel)和一系列项目(item)组成,其中频道包括标题(title),链接(link),描述(descroiption)和语言(language,
可选)组成,一个项目由标题,链接和描述组成。
现在我们来看看RSS 1.0的例子:
<rdf:RDF
xmlns:rdf="http://www.w3.org/ 1999/02/22 -rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<channel rdf:about="http://www.xml.com/cs/xml/query/q/19">
<title>XML.com</title>
<link>http://www.xml.com/</link>
<description>XML.com features a rich mix of information and services for the XML community.</description>
<language>en-us</language>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html"/>
<rdf:li rdf:resource="http://www.xml.com/pub/a/ 2002/12/04 /som.html"/>
<rdf:li rdf:resource="http://www.xml.com/pub/a/ 2002/12/04 /svg.html"/>
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html">
<title>Normalizing XML, Part 2</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html</link>
<description>In this second and final look at applying relational normalization techniques to W 3C XML Schema data modeling, Will Provost discusses when not to normalize, the scope of uniqueness and the fourth and fifth normal forms.</description>
<dc:creator>Will Provost</dc:creator>
<dc:date> 2002-12-04 </dc:date>
</item>
<item rdf:about="http://www.xml.com/pub/a/ 2002/12/04 /som.html">
<title>The .NET Schema Object Model</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /som.html</link>
<description>Priya Lakshminarayanan describes in detail the use of the .NET Schema Object Model for programmatic manipulation of W 3C XML Schemas.</description>
<dc:creator>Priya Lakshminarayanan</dc:creator>
<dc:date> 2002-12-04 </dc:date>
</item>
<item rdf:about="http://www.xml.com/pub/a/ 2002/12/04 /svg.html">
<title>SVG's Past and Promising Future</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /svg.html</link>
<description>In this month's SVG column, Antoine Quint looks back at SVG's journey through 2002 and looks forward to 2003.</description>
<dc:creator>Antoine Quint</dc:creator>
<dc:date> 2002-12-04 </dc:date>
</item>
</rdf:RDF>
有一点冗长。对RDF熟悉的人会把它当作是一个XML和RDF综合的文档;其它人至少会认出我们聚合了同样的信息。事实上,我们包含了更多的信息:项目层的
作者和出版日期,这是0.91版所不支持的。
尽管来源于RDF/XML,RSS 1.0在结构上跟先前的RSS版本还是相似的--相似到我们可以简单地把它当作一个XML并且可以只写一个函数来提取RSS 0.91或者
RSS 1.0中的feed的信息。尽管如此,在我们的代码中应该明白一些两者之间明显的不同之处:
1,根元素是"rdf:RDF"而不是"rss"。我们可以显式地处理两者或者完成忽略根元素的名字而只搜索有用的信息。
2,RSS 1.0广泛地使用了名字空间。RSS 1.0的默认名字空间是"http://purl.org/rss/1.0/"。feed也使用"http://www.w3.org/ 1999/02/22 -rdf-syntax-ns#"作为RDF-specific元素的名字空间,使用"http://purl.org/dc/elements/1.1/"(Dublin Core)作为额外的元数据--文章作者和出版日期的名字空间。
在这里我们的两种方式:如果我们没有可明白名字空间的剖析器,我们可以默认feed使用标准的前缀和默认的名字空间,并且寻找其中的item和dc:create元素。实际应用中大多采用这种方式;大多数的RSS feeds使用默认的名字空间和同样的通用模块前缀例如Dublin Core。但这不是说feed不能使用其他的名字空间(有名字空间会完善合法的XML和RDF文件)。
如果我们有可以明白名字空间的剖析器,我们可以构造一个更好的解决方案来同时处理RSS 0.91和RSS 1.0的feeds。我们可以寻找没有名字空间的item,如果失败则寻找RSS 1.0的名字空间中的item。(尽管没有显示出来,但是RSS 0.90的feeds同样可以使用namespace,不过与RSS 1.0的不同。所以我们真正需要的是搜寻名字空间列表。)
3,不是很明显但还是很重要的是,item的元素是在channel元素的外部的。(在RSS 0.91中,item元素是在channel元素重的。在RSS 0.90中,在外部;在RSS 2.0中,在内部。)因此我们不能过分强求在哪找到item。
4,最后,你会在channel中发现额外的item元素。它只是用于RDF剖析器,我们可以忽略它并且假定RSS feed中的items的顺序就是items元素的顺序。
那么RSS 2.0呢?幸运的是,如果我们写了处理RSS 0.91和RSS 1.0的代码后,RSS 2.0就是小菜一碟了。这里是RSS 2.0 feed的例子:
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>XML.com</title>
<link>http://www.xml.com/</link>
<description>XML.com features a rich mix of information and services for the XML community.</description>
<language>en-us</language>
<item>
<title>Normalizing XML, Part 2</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html</link>
<description>In this second and final look at applying relational normalization techniques to W 3C XML Schema data modeling, Will Provost discusses when not to normalize, the scope of uniqueness and the fourth and fifth normal forms.</description>
<dc:creator>Will Provost</dc:creator>
<dc:date> 2002-12-04 </dc:date>
</item>
<item>
<title>The .NET Schema Object Model</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /som.html</link>
<description>Priya Lakshminarayanan describes in detail the use of the .NET Schema Object Model for programmatic manipulation of W 3C XML Schemas.</description>
<dc:creator>Priya Lakshminarayanan</dc:creator>
<dc:date> 2002-12-04 </dc:date>
</item>
<item>
<title>SVG's Past and Promising Future</title>
<link>http://www.xml.com/pub/a/ 2002/12/04 /svg.html</link>
<description>In this month's SVG column, Antoine Quint looks back at SVG's journey through 2002 and looks forward to 2003.</description>
<dc:creator>Antoine Quint</dc:creator>
<dc:date> 2002-12-04 </dc:date>
</item>
</channel>
</rss>
就像例子显示的一样,象RSS 1.0一样,RSS 2.0也使用名字空间,但不是RDF。象RSS 0.91一样,没有默认的名字空间并且items在channel的底部。如果你的代码能够自由的处理RSS 0.91和RSS 1.0,那么RSS 2.0不会有任何麻烦。
我怎么才能阅读RSS?
现在我们来看看怎么用Python来读RSS feed.我们首先要做的是下载一些RSS feeds。在Python中这很简单:大多数同时具有URL取回库和XML剖析器。(对于Mac OS X 10.2的用户来说,你们所用的Python中并没有XML剖析器,需要先安装PyXML)。
from xml.dom import minidom
import urllib
def load(rssURL):
return minidom.parse(urllib.urlopen(rssURL))
载入RSS feed所在的URL,并返回DOM的解析,就像一般的Python对象。
为了找出RSS 格式之间的差异,我们需要一个函数来搜索任意个名字空间中定义的元素。Python的XML库中包含一个getElementsByTagNameNS的函数,可以用来处理一个名字空间和一个已标识的名字,所以我们可以使用它来势我们的代码能处理RSS 0.9X/2.0(没有默认名字空间),RSS 1.0甚至RSS 0.90。这个函数会在节点中的任何位置找到该给出名字的任何元素。这是件好事,我们可以在根节点中搜寻item并可以总是找到它们,不论它们是在channel的内部还是外部。
DEFAULT_NAMESPACES = /
(None, # RSS 0.91, 0.92, 0.93, 0.94, 2.0
'http://purl.org/rss/1.0/', # RSS 1.0
'http://my.netscape.com/rdf/simple/0.9/' # RSS 0.90
)
def getElementsByTagName(node, tagName,
possibleNamespaces=DEFAULT_NAMESPACES):
for namespace in possibleNamespaces:
children = node.getElementsByTagNameNS(namespace, tagName)
if len(children): return children
return []
最后,我们需要两个效用函数来使我们的生活变得简单。首先,我们的getElementByTagName函数将返回一系列元素,但是大多数时间我们知道只会返回一个。例如,一个item只有一个title,一个link,一个description。我们需要定义一个first函数来返回第一个元素的已标识名字(还是搜索不同的名字空间)。接着,Python的XML库能很好地将XML文件剖析到节点中,但是在将返回数据并集合起来方面帮助不大。我们需要定义一个textOf函数用来返回一个特定的XML元素的整个正文。
def first(node, tagName, possibleNamespaces=DEFAULT_NAMESPACES):
children = getElementsByTagName(node, tagName, possibleNamespaces)
return len(children) and children[0] or None
def textOf(node):
return node and "".join([child.data for child in node.childNodes]) or ""
就这样,事实上剖析很简单。我们在命令行输入一个URL,下载它,剖析它,得到items的列表,接着在每个item中获取有用信息。
DUBLIN_CORE = ('http://purl.org/dc/elements/1.1/',)
if __name__ == '__main__':
import sys
rssDocument = load(sys.argv[1])
for item in getElementsByTagName(rssDocument, 'item'):
print 'title:', textOf(first(item, 'title'))
print 'link:', textOf(first(item, 'link'))
print 'description:', textOf(first(item, 'description'))
print 'date:', textOf(first(item, 'date', DUBLIN_CORE))
print 'author:', textOf(first(item, 'creator', DUBLIN_CORE))
如果用来剖析RSS 0.91 feed的例子,将只会显示title,link,description(因为RSS 0.91 feed中没有包含dates和authors)。
$ python rss1.py http://www.xml.com/ 2002/12/18 /examples/rss091.xml.txt
title: Normalizing XML, Part 2
link: http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html
description: In this second and final look at applying relational normalization techniques to W 3C XML Schema data modeling, Will Provost discusses when not to normalize, the scope of uniqueness and the fourth and fifth normal forms.
date:
author:
title: The .NET Schema Object Model
link: http://www.xml.com/pub/a/ 2002/12/04 /som.html
description: Priya Lakshminarayanan describes in detail the use of the .NET Schema Object Model for programmatic manipulation of W 3C XML Schemas.
date:
author:
title: SVG's Past and Promising Future
link: http://www.xml.com/pub/a/ 2002/12/04 /svg.html
description: In this month's SVG column, Antoine Quint looks back at SVG's journey through 2002 and looks forward to 2003.
date:
author:
对于RSS 1.0 feed和RSS 2.0 feed的例子来说,我们可以得到每个item的dates和authors。我们将重用getElementsByTagName函数,但是使用名字空间Dublin Core和合适的已标识名字。我们能重用同样的函数来获取基本RSS模块的信息。(RSS 1.0中有一些高级模块要用的RDF剖析器,但是在RSS feeds中没有广泛使用)。
这里是RSS 1.0 feed的例子输出的结果:
$ python rss1.py http://www.xml.com/ 2002/12/18 /examples/rss10.xml.txt
title: Normalizing XML, Part 2
link: http://www.xml.com/pub/a/ 2002/12/04 /normalizing.html
description: In this second and final look at applying relational normalization techniques to W 3C XML Schema data modeling, Will Provost discusses when not to normalize, the scope of uniqueness and the fourth and fifth normal forms.
date: 2002-12-04
author: Will Provost
title: The .NET Schema Object Model
link: http://www.xml.com/pub/a/ 2002/12/04 /som.html
description: Priya Lakshminarayanan describes in detail the use of the .NET Schema Object Model for programmatic manipulation of W 3C XML Schemas.
date: 2002-12-04
author: Priya Lakshminarayanan
title: SVG's Past and Promising Future
link: http://www.xml.com/pub/a/ 2002/12/04 /svg.html
description: In this month's SVG column, Antoine Quint looks back at SVG's journey through 2002 and looks forward to 2003.
date: 2002-12-04
author: Antoine Quint
运行RSS 2.0 feed的例子也会输出以上结果。
这种方法能处理大约90%的RSS feeds;剩下来的会产生各种有趣的错误,大部分是因为feeds是使用不明白XML的发布工具产生的,
不遵守XML的基本规则。