the5fire的技术博客

关注Python、Django、Vim、Linux、Web开发、团队管理和互联网--Life is short, we need Python.


python项目练习四:新闻聚合

作者:the5fire | 标签:   | 发布:2011-12-26 10:07 p.m. | 阅读量: 38210, 37179

书中的第四个练习,新闻聚合。现在很少见的一类应用,至少我从来没有用过,又叫做Usenet。这个程序的主要功能是用来从指定的来源(这里是Usenet新闻组)收集信息,然后讲这些信息保存到指定的目的文件中(这里使用了两种形式:纯文本和html文件)。这个程序的用处有些类似于现在的博客订阅工具或者叫RSS订阅器。

先上代码,然后再来逐一分析:

fromnntplibimportNNTPfromtimeimportstrftime,time,localtimefromemailimportmessage_from_stringfromurllibimporturlopenimporttextwrapimportreday=24*60*60defwrap(string,max=70):'''

        '''return'\n'.join(textwrap.wrap(string))+'\n'classNewsAgent:'''
        '''def__init__(self):self.sources=[]self.destinations=[]defaddSource(self,source):self.sources.append(source)defaddDestination(self,dest):self.destinations.append(dest)defdistribute(self):items=[]forsourceinself.sources:items.extend(source.getItems())fordestinself.destinations:dest.receiveItems(items)classNewsItem:def__init__(self,title,body):self.title=titleself.body=bodyclassNNTPSource:def__init__(self,servername,group,window):self.servername=servernameself.group=groupself.window=windowdefgetItems(self):start=localtime(time()-self.window*day)date=strftime('%y%m%d',start)hour=strftime('%H%M%S',start)server=NNTP(self.servername)ids=server.newnews(self.group,date,hour)[1]foridinids:lines=server.article(id)[3]message=message_from_string('\n'.join(lines))title=message['subject']body=message.get_payload()ifmessage.is_multipart():body=body[0]yieldNewsItem(title,body)server.quit()classSimpleWebSource:def__init__(self,url,titlePattern,bodyPattern):self.url=urlself.titlePattern=re.compile(titlePattern)self.bodyPattern=re.compile(bodyPattern)defgetItems(self):text=urlopen(self.url).read()titles=self.titlePattern.findall(text)bodies=self.bodyPattern.findall(text)fortitle.bodyinzip(titles,bodies):yieldNewsItem(title,wrap(body))classPlainDestination:defreceiveItems(self,items):foriteminitems:printitem.titleprint'-'*len(item.title)printitem.bodyclassHTMLDestination:def__init__(self,filename):self.filename=filenamedefreceiveItems(self,items):out=open(self.filename,'w')print>>out,'''
                <html>
                <head>
                 <title>Today's News</title>
                </head>
                <body>
                <h1>Today's News</hi>
                '''print>>out,'<ul>'id=0foriteminitems:id+=1print>>out,'<li><a href="#">%s</a></li>'%(id,item.title)print>>out,'</ul>'id=0foriteminitems:id+=1print>>out,'<h2><a name="%i">%s</a></h2>'%(id,item.title)print>>out,'<pre>%s</pre>'%item.bodyprint>>out,'''
                </body>
                </html>
                '''defrunDefaultSetup():agent=NewsAgent()bbc_url='http://news.bbc.co.uk/text_only.stm'bbc_title=r'(?s)a href="[^"]*">\s*<b>\s*(.*?)\s*</b>'bbc_body=r'(?s)</a>\s*<br/>\s*(.*?)\s*<'bbc=SimpleWebSource(bbc_url,bbc_title,bbc_body)agent.addSource(bbc)clpa_server='news2.neva.ru'clpa_group='alt.sex.telephone'clpa_window=1clpa=NNTPSource(clpa_server,clpa_group,clpa_window)agent.addSource(clpa)agent.addDestination(PlainDestination())agent.addDestination(HTMLDestination('news.html'))agent.distribute()if__name__=='__main__':runDefaultSetup()

这个程序,首先从整体上进行分析,重点部分在于NewsAgent,它的作用是存储新闻来源,存储目标地址,然后在分别调用来源服务器(NNTPSource以及SimpleWebSource)以及写新闻的类(PlainDestination和HTMLDestination)。所以从这里也看的出,NNTPSource是专门用来获取新闻服务器上的信息的,SimpleWebSource是获取一个url上的数据的。而PlainDestination和HTMLDestination的作用很明显,前者是用来输出获取到的内容到终端的,后者是写数据到html文件中的。

有了这些分析,然后在来看主程序中的内容,主程序就是来给NewsAgent添加信息源和输出目的地址的。

这确实是个简单的程序,不过这个程序可是用到了分层了。

2017-05-15更新:

http://the5fireblog.b0.upaiyun.com/staticfile/django-tech-end-article.png
- from the5fire.com
----EOF-----

微信公众号:Python程序员杂谈

最后两周预售价


其他分类: