這邊簡單說一下最近倒騰的RSS閱讀器的小東東,RSS閱讀器估計不少人用過或者本身動手實現過。首先wudagang0123多年前提供的一個示例:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1559320,在其基礎上,增長了一些功能,能夠解析ATOM和RSS的feed格式規範,優化了程序界面,主要目的是學習了下wxpython和XML解析的一些東西。程序預覽以下:php
1 def SaveChannelToFile(self): 2 impl = minidom.getDOMImplementation() 3 dom = impl.createDocument(None,'channel',None) 4 root = dom.documentElement 5 #add old 6 add_node = None 7 xmldoc = minidom.parse('channel.xml') 8 groups = xmldoc.getElementsByTagName('group') 9 for group in groups: 10 root.appendChild(group) 11 if group.getElementsByTagName('name')[0].firstChild.data == self.groupCombo.GetValue(): 12 add_node = group 13 #add new 14 15 xmldoc2 = minidom.parse(sysutils.XML_DIR+sysutils.replace_filename(self.url)) 16 channel = xmldoc2.getElementsByTagName('channel') 17 if not channel: 18 channel = xmldoc2.getElementsByTagName('feed') 19 if channel: 20 self.rssmode = "atom" 21 else: 22 return 23 else: 24 self.rssmode = "rss" 25 channel_title = channel[0].getElementsByTagName('title')[0].firstChild.data 26 item_node = dom.createElement('item') 27 title_node = dom.createElement('title') 28 title_text = dom.createTextNode(channel_title) 29 mode_node = dom.createElement('mode') 30 mode_text = dom.createTextNode(self.rssmode) 31 link_node = dom.createElement('link') 32 link_text = dom.createTextNode(self.url) 33 title_node.appendChild(title_text) 34 mode_node.appendChild(mode_text) 35 link_node.appendChild(link_text) 36 item_node.appendChild(title_node) 37 item_node.appendChild(mode_node) 38 item_node.appendChild(link_node) 39 add_node.appendChild(item_node) 40 41 f = open('channel.xml','wb') 42 writer = codecs.lookup('utf-8')[3](f) 43 dom.writexml(writer,encoding='utf-8') 44 writer.close() 45 f.close()
RSS閱讀器的實現原理無非是利用python的模塊解析RSS格式文件,將XML文件中的文章地址提取出來,實現新聞和消息的聚合。python這邊專門處理RSS的模塊有比較不錯的,Universal Feed Parser。這邊沒有引入太複雜模塊來實現XML的解析的必要。主要用到了python中的小型處理模塊Minidom來處理XML文件。主要處理以下: html
根據xml文件是否存在channel或者feed標籤來區分RSS地址源中RSS和atom兩種格式,對XML文件首先提取標題存儲到本地channel.XML文件,該文件記錄了咱們收錄的主要頻道信息,同時將每一個頻道對應的xml文件下載到本地進行保存。新建的channel.xml內容以下:node
1 <?xml version="1.0" encoding="utf-8"?><channel> 2 <group> 3 <name>技術頻道</name> 4 <item><title>博客園_python學習</title> 5 <mode>atom</mode> 6 <link>http://feed.cnblogs.com/blog/u/43317/rss</link> 7 </item> 8 <item><title>博客園_KillConsole</title> 9 <mode>atom</mode> 10 <link>http://feed.cnblogs.com/blog/u/131263/rss</link></item></group><group> 11 <name>體育頻道</name> 12 </group></channel>
得到了下載到的XML文件以後,就能夠根據改文件進一步解析獲取每一個頻道下面的文章了。python
1 def UpdateItemList(self,filename,root): 2 self.ChannelTree.DeleteChildren(root) 3 self.rssmode = self.ModeMap[self.ChannelTree.GetItemText(root)] 4 if self.rssmode == "rss": 5 self.UpdateRSSList(filename,root) 6 elif self.rssmode == "atom": 7 self.UpdateAtomList(filename,root) 8 9 def UpdateAtomList(self,filename,root): 10 xmldoc = minidom.parse(filename) 11 items = xmldoc.getElementsByTagName('entry') 12 for item in items: 13 item_title=[] 14 titles = item.getElementsByTagName('title') 15 for title in titles: 16 newitem = self.ChannelTree.AppendItem(root,title.firstChild.data) 17 title_text=self.ChannelTree.GetItemText(newitem).encode('utf-8') 18 item_title.append(title_text) 19 index = 0 20 links = item.getElementsByTagName('id') 21 for link in links: 22 self.ItemMap[item_title[index]]=link.firstChild.data 23 index+=1 24 def UpdateRSSList(self,filename,root): 25 xmldoc = minidom.parse(filename) 26 items = xmldoc.getElementsByTagName('item') 27 for item in items: 28 item_title=[] 29 titles = item.getElementsByTagName('title') 30 for title in titles: 31 newitem = self.ChannelTree.AppendItem(root,title.firstChild.data) 32 title_text=self.ChannelTree.GetItemText(newitem).encode('utf-8') 33 item_title.append(title_text) 34 index = 0 35 links = item.getElementsByTagName('link') 36 for link in links: 37 self.ItemMap[item_title[index]]=link.firstChild.data 38 index+=1
利用wxpython樹形控件響應標題的雙擊事件,根據標題對應的LINK地址來打開對應的網頁,即HtmlView.LoadUrl(url) 來實現打開指定網頁界面。
另外程序還實現了頻道和頻道組的添加和刪除,功能比較簡單可是能夠知足基本的需求了。app