|
这边简单说一下最近倒腾的RSS阅读器的小东东,RSS阅读器估计很多人用过或者自己动手实现过。首先wudagang0123多年前提供的一个示例:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1559320,在其基础上,增加了一些功能,可以解析ATOM和RSS的feed格式规范,优化了程序界面,主要目的是学习了下wxpython和XML解析的一些东西。程序预览如下:

 
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()
View Code RSS阅读器的实现原理无非是利用python的模块解析RSS格式文件,将XML文件中的文章地址提取出来,实现新闻和消息的聚合。python这边专门处理RSS的模块有比较不错的,Universal Feed Parser。这边没有引入太复杂模块来实现XML的解析的必要。主要用到了python中的小型处理模块Minidom来处理XML文件。主要处理如下:
根据xml文件是否存在channel或者feed标签来区分RSS地址源中RSS和atom两种格式,对XML文件首先提取标题存储到本地channel.XML文件,该文件记录了我们收录的主要频道信息,同时将每个频道对应的xml文件下载到本地进行保存。新建的channel.xml内容如下:
1
2
3 技术频道
4 博客园_python学习
5 atom
6 http://feed.iyunv.com/blog/u/43317/rss
7
8 博客园_KillConsole
9 atom
10 http://feed.iyunv.com/blog/u/131263/rss
11 体育频道
12
获得了下载到的XML文件之后,就可以根据改文件进一步解析获取每个频道下面的文章了。
 
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
View Code 利用wxpython树形控件响应标题的双击事件,根据标题对应的LINK地址来打开对应的网页,即HtmlView.LoadUrl(url) 来实现打开指定网页界面。
另外程序还实现了频道和频道组的添加和删除,功能比较简单但是可以满足基本的需求了。
|
|
|