python基础教程项目四之新闻聚合
《python基础教程》书中的第四个练习,新闻聚合。现在很少见的一类应用,至少我从来没有用过,又叫做Usenet。这个程序的主要功能是用来从指定的来源(这里是Usenet新闻组)收集信息,然后讲这些信息保存到指定的目的文件中(这里使用了两种形式:纯文本和html文件)。这个程序的用处有些类似于现在的博客订阅工具或者叫RSS订阅器。
先上代码,然后再来逐一分析:
fromnntplibimportNNTP fromtimeimportstrftime,time,localtime fromemailimportmessage_from_string fromurllibimporturlopen importtextwrap importre day=24*60*60 defwrap(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=title self.body=body classNNTPSource: def__init__(self,servername,group,window): self.servername=servername self.group=group self.window=window defgetItems(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=url self.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.title print'-'*len(item.title) printitem.body classHTMLDestination: def__init__(self,filename): self.filename=filename defreceiveItems(self,items): out=open(self.filename,'w') print>>out,'''Today'sNews Today'sNews ''' print>>out,'
' id=0 foriteminitems: id+=1 print>>out,'
' id=0 foriteminitems: id+=1 print>>out,'- '%(id,item.title) print>>out,'
%s '%(id,item.title) print>>out,'
%s %s'%item.body print>>out,''' ''' defrunDefaultSetup(): agent=NewsAgent() bbc_url='http://news.bbc.co.uk/text_only.stm' bbc_title=r'(?s)ahref="[^"rel="externalnofollow"]*">\s*\s*(.*?)\s*' bbc_body=r'(?s)\s*
\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=1 clpa=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添加信息源和输出目的地址的。
这确实是个简单的程序,不过这个程序可是用到了分层了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。