天天看點

項目4:新聞聚合

所謂的新聞聚合就是搜集新聞資訊吧,其中需要從nntplib子產品來導入NNTP伺服器,搜了幾個免費NNTP伺服器還是沒效果,還需要urllib子產品,我想之後的網絡爬蟲會用到這個來下載下傳源代碼資源,還需要re子產品,裡面的正規表達式真正的太有壓力了。

正則得看看,先看code:

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 seld.distinations:
            dest.receiveItems(items)

class NewsItem:
    """
    包括标題和主題文本的簡單新聞項目
    """
    def __init__(self,title,body):
        self.title=title
        self.body=body

class 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,datahour)[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 mssage.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.finall(text)
        bodies=self.bodyPattern.finall(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:
    """
    将所有新聞項目格斯會話為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</h1>
            """

        print >>out,'<u1>'
        id=0
        for item in items:
            id+=1
            print >>out,'<li><a href="#%i" target="_blank" rel="external nofollow" >%s</a></li>'%(id,item.title)
            print >>out,'</u1>'

            id=0
            for item in items:
                id+=1
                print >>out,'<h2><a name="%i">%s</a></h2>'%(id,item.title)
                print >>out,'<pre>%</pre>'%item.body

            print >>out,"""
            </body>
        </html>
        """


    
def runDefaultSetup():

        agent = NewsAgent()

        bbc_url = 'http://news.bbc.co.uk/text_only.stm'
        bbc_title = r'(?s)a href="[^" target="_blank" rel="external nofollow" ]*">\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 = 'neontetra.realize.com'
        clpa_group = 'comp.lang.python.announce'
        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()        
        
           

先調用runDefaultSetup()來擷取新聞來源,先後生成類NewsAgent和SimpleWebSource的執行個體,擷取新聞的來源,其中 類SimpleWebSource實作了下載下傳新聞資源的功能,title和bodies經過zip()變成元組清單。Agent.addSource()把來源放到目标對象source清單中。NNTPSource用于從NNTP組中擷取新聞項目的來源,并且可以指定time,PlianDestination會輸出手機的新聞資源,HTMLDestination會生成html頁面.不會正規表達式是真的看不懂怎麼比對需要搜集的資源的。

繼續閱讀