python项目练习四:新闻聚合

书中的第四个练习,新闻聚合。现在很少见的一类应用,至少我从来没有用过,又叫做Usenet。这个程序的主要功能是用来从指定的来源(这里是Usenet新闻组)收集信息,然后讲这些信息保存到指定的目的文件中(这里使用了两种形式:纯文本和html文件)。这个程序的用处有些类似于现在的博客订阅工具或者叫RSS订阅器。

先上代码,然后再来逐一分析:

.. code:: python

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,'''
                <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()

        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)

        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添加信息源和输出目的地址的。

这确实是个简单的程序,不过这个程序可是用到了分层了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏无原型不设计

12个最佳的响应式网页设计教程,轻松带你入门!

如何让你的网站在其出现的任何设备和屏幕尺寸上能够完美的呈现?响应式设计完美的解决了这一难题,作为现在的网页设计师都应该了解响应式网页设计的原则。而对于刚步入网页...

32940
来自专栏无原型不设计

交互神器-最好用的Mac原型设计工具

市场上有着大量的开发和设计工具支持在Mac上安装使用,今天给大家强烈推荐一款Mac上的原型设计工具-Mockplus,原型工具在产品开发设计中是必不可少的,无论...

20920
来自专栏javascript趣味编程

2.3.1 基于easyUI框架写加法器

easyUI是一个第三方控件库,内容很全面。比如我们做一个加法计算程序,打开其官网,找到示例修改到自己想要的结果。先找到其相关内容:

16710
来自专栏机器人课程与技术

在Ubuntu 18.04 LTS试用ROS Melodic版机器人操作系统

在Ubuntu 18.04 LTS安装ROS Melodic版机器人操作系统,参考如下链接:

15020
来自专栏javascript趣味编程

2.3.2 基于bootstrap框架写加法器

什么是bootstrap?一套用js和CSS编写的框架模板,自己组装一下就可以编写比较美观的网页。官当介绍是组件库:

8410
来自专栏鸿的学习笔记

重新理解经济

近日重读了《经济机器是怎样运行的》,再结合现在的时事,顿时明白了好多东西。拂去纷纷扰扰,借由这篇文章从一个小白的角度重新理解经济。

10620
来自专栏编码前线

使用FindBugs插件检查Android代码

13730
来自专栏编程坑太多

「小程序JAVA实战」小程序视频组件与api介绍(51)

如果想在video组件上添加组件,可以使用cover-view组件,具体使用方法点击这里:https://mp.weixin.qq.com/debug/wxad...

13330
来自专栏java一日一条

详细介绍Spring 5的那些新特性与增强『文末送书』

Spring支持不同的scope。不同scope在使用上是有差异的,比如singleton与prototype。

13710
来自专栏美码师

补习系列(12)-springboot 与邮件发送

SMTP 是 Simple Mail Transfer Protocol 的简称,即简单邮件传输协议,是发送协议。 它定义了一组从源地址到目的地址传输邮件的规范...

15920

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励