《python基础教程》书中的第四个练习,新闻聚合。现在很少见的一类应用,至少我从来没有用过,又叫做Usenet。这个程序的主要功能是用来从指定的来源(这里是Usenet新闻组)收集信息,然后讲这些信息保存到指定的目的文件中(这里使用了两种形式:纯文本和html文件)。这个程序的用处有些类似于现在的博客订阅工具或者叫RSS订阅器。
先上代码,然后再来逐一分析:
from nntplib import NNTP
from time import strftime,time,localtime
from email import message_from_string
from urllib import urlopen
import textwrap
import re
day = 24*60*60
def 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 = body
class NNTPSource:
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:
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.body
class HTMLDestination:
def __init__(self,filename):
self.filename = filename
def receiveItems(self,items):
out = open(self.filename,'w')
print >> out,'''
Today's News
Today's News
'''
print >> out, '%s' % item.body print >> out, '''