標籤:
NNTP:網路新聞傳輸通訊協定,Network News Transfer Protocol
目標:
從多種不同的來源收集新聞;
使用者可以輕鬆添加新的新聞來源(甚至是新類型的新聞來源;
程式可以將編譯好的新聞報告指派出多個不同格式的目標;
程式可以輕鬆添加新的目標(甚至是新種類的目標)
1. 簡單的新聞代理程式
1)NNTP類對象:使用NNTP伺服器名字執行個體化;
newnews方法: 返回給定日期時間之後發布的文章;
head方法:提供關於檔案(主要是主題)的各種資訊;
body方法:提供文章的本文
2)time.localtime([ sec ]) : 將秒數sec轉換為time.struct_time類型的對象
time.strftime(format[, t]) : format -- 格式字串, t -- 可選的參數t是一個struct_time對象 返回以可讀字串表示的時間
#newsagent1.pyfrom nntplib import NNTPfrom time import strftime, time, localtimeday=24*60*60yesterday=localtime(time()-day)date=strftime(‘%y%m%d‘, yesterday)hour=strftime(‘%H%M%S‘, yesterday)servername=‘news.foo.bar‘ #虛構的伺服器名group=‘comp.lang.python.announce‘sever=NNTP(servername)ids=server.newnews(group.date.hour)[1] #提取newnews方法返回元組的第二個參數,即發表文章的ID號for id in ids: head=server.head(id)[3] #返回資訊元組的第四個元素:字串列表(資料本身) for line in head: if line.lower().startswitch(‘subject:‘): subject= line[9:] break body=server.body(id)[3] print subject print ‘-‘*len(subject) print ‘\n‘.join(body)server.quit()
2. 改進
from nntplib import NNTPfrom time import strftime,time,localtimefrom email import message_from_stringfrom urllib import urlopenimport textwrapimport reday = 24*60*60def wrap(string,max=70): ‘‘‘ 將字串調整為最大行寬 ‘‘‘ return ‘\n‘.join(textwrap.wrap(string)) + ‘\n‘class NewsAgent: ‘‘‘ 可以從新聞來源擷取新聞項目並且發布到新聞目標的對象 ‘‘‘ def __init__(self): self.sources = [] self.destinations = [] def addSource(self,source): self.sources.append(source) def addDestination(self,dest): self.destinations.append(dest) def distribute(self): ‘‘‘ 從所有來源擷取所有新聞項目並且發布到所有目標 ‘‘‘ items = [] for source in self.sources: items.extend(source.getItems()) for dest in self.destinations: dest.receiveItems(items)class NewsItem: ‘‘‘ 包括標題和主題文本的簡單新聞項目 ‘‘‘ def __init__(self,title,body): self.title = title self.body = bodyclass NNTPSource: ‘‘‘ 從NNTP組中擷取新聞項目的新聞來源 ‘‘‘ def __init__(self,servername,group,window): self.servername = servername self.group = group self.window = window def getItems(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] for id in ids: lines = server.article(id)[3] message = message_from_string(‘\n‘.join(lines)) title = message[‘subject‘] body = message.get_payload() if message.is_multipart(): body = body[0] yield NewsItem(title,body) server.quit()class SimpleWebSource: ‘‘‘ 使用Regex從網頁中提取新聞項目的新聞來源 ‘‘‘ def __init__(self,url,titlePattern,bodyPattern): self.url = url self.titlePattern = re.compile(titlePattern) self.bodyPattern = re.compile(bodyPattern) def getItems(self): text = urlopen(self.url).read() titles = self.titlePattern.findall(text) bodies = self.bodyPattern.findall(text) for title.body in zip(titles,bodies): yield NewsItem(title,wrap(body))class PlainDestination: ‘‘‘ 將所有的新聞項目格式化為純文字的新聞目錄類 ‘‘‘ def receiveItems(self,items): for item in items: print item.title print ‘-‘*len(item.title) print item.bodyclass HTMLDestination: ‘‘‘ 將所有的新聞項目格式化為HTML的目標類 ‘‘‘ def __init__(self,filename): self.filename = filename def receiveItems(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 = 0 for item in items: id += 1 print >> out, ‘<li><a href="#">%s</a></li>‘ % (id,item.title) print >> out, ‘</ul>‘ id = 0 for item in items: id += 1 print >> out, ‘<h2><a name="%i">%s</a></h2>‘ % (id,item.title) print >> out, ‘<pre>%s</pre>‘ % item.body print >> out, ‘‘‘ </body> </html> ‘‘‘def runDefaultSetup(): ‘‘‘ 來源和目標的預設位置,可以修改 ‘‘‘ agent = NewsAgent() ‘‘‘ 從BBS新聞站擷取新聞的SimpleWebSource ‘‘‘ 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) ‘‘‘ 從comp.lang.python.announce擷取新聞的NNTPSource ‘‘‘ clpa_server = ‘news2.neva.ru‘ clpa_group = ‘alt.sex.telephone‘ clpa_window = 1 clpa = NNTPSource(clpa_server,clpa_group,clpa_window) agent.addSource(clpa) ‘‘‘ 增加純文字目標和HTML目標 ‘‘‘ 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添加資訊源和輸出目的地址的。
python基礎教程總結15——4 新聞彙總