zoukankan      html  css  js  c++  java
  • python基础教程总结15——4 新闻聚合

    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.py
    from nntplib import NNTP
    from time import strftime, time, localtime
    
    day=24*60*60
    yesterday=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 '
    '.join(body)
    
    server.quit()

    2. 改进

    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 '
    '.join(textwrap.wrap(string)) + '
    '
    
    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:
            '''
            从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('
    '.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:
            '''
            将所有的新闻项目格式化为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添加信息源和输出目的地址的。

  • 相关阅读:
    2020软件工程第二次作业
    软件工程第一次作业
    2020软件工程最后一次作业
    2020软件工程第四次作业-结对编程
    2020软件工程第三次作业-结对编程
    2020软件工程第二次作业
    如何在Anaconda3下打开ipynb文件
    2020软件工程第一次作业
    软件代码开发技术作业五 | 代码开发、测试及发布
    需求改进&系统设计
  • 原文地址:https://www.cnblogs.com/zxqstrong/p/4682934.html
Copyright © 2011-2022 走看看