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中的輸出相同。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
