zoukankan      html  css  js  c++  java
  • RSS阅读器python实现概述

      这边简单说一下最近倒腾的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 <?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文件之后,就可以根据改文件进一步解析获取每个频道下面的文章了。

     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) 来实现打开指定网页界面。
      另外程序还实现了频道和频道组的添加和删除,功能比较简单但是可以满足基本的需求了。

      

  • 相关阅读:
    java语法基础
    HashMap中的put()和get()的实现原理
    理解:o(1), o(n), o(logn), o(nlogn) 时间复杂度
    mongodb去重分页查询支持排序
    elk日志分析系统搭建(window )亲自搭建
    IDEA更改主题插件——Material Theme UI
    css实现图片的瀑布流且右上角有计数
    C# string "yyMMdd" 转DataTime
    Vue.js系列(一):Vue项目创建详解
    VS2017常用快捷键
  • 原文地址:https://www.cnblogs.com/lophy/p/3490526.html
Copyright © 2011-2022 走看看