python基础教程项目四之新闻聚合

《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,'''
        <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="#" rel="external nofollow" >%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="[^" 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 = '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添加信息源和输出目的地址的。

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • python基础教程之数字处理(math)模块详解
  • python基础教程之popen函数操作其它程序的输入和输出示例
  • python基础教程之类class定义使用方法
  • python基础教程之基本数据类型和变量声明介绍
  • python基础教程之lambda表达式使用方法
  • Python安装使用命令行交互模块pexpect的基础教程
  • python基础教程之实现石头剪刀布游戏示例
  • python基础教程项目三之万能的XML
  • python基础教程项目二之画幅好画
  • python基础教程项目五之虚拟茶话会
(0)

相关推荐

  • python基础教程之实现石头剪刀布游戏示例

    下面是规则.你和你的对手,在同一时间做出特定的手势,必须是下面一种手势:石头,剪子,布.胜利者从下面的规则中产生,这个规则本身是个悖论.(a) 布包石头.(b)石头砸剪子,(c)剪子剪破布.在你的计算机版本中,用户输入她/他的选项,计算机找一个随机选项,然后由你的程序来决定一个胜利者或者平手.注意:最好的算法是尽量少的使用 if 语句 复制代码 代码如下: #coding:utf-8 import randomguess_list = ["石头","剪刀",&quo

  • python基础教程项目五之虚拟茶话会

    几乎在学习.使用任何一种编程语言的时候,关于socket的练习从来都不会少,尤其是会写一些局域网的通信的东西.所以书上的这个项目刚好可以练习一下socket编程. 这个练习的整体思路首先有一个聊天的服务器,这个服务器的功能主要是提供客户端socket的连接.存储每个客户端的连接session,处理每个连接发送的消息.解析客户端发送的数据.就这些,至于客户端方面不需要写代码,用系统的telnet工具即可. 我觉得有了上面的分析,剩下的这个程序就没有什么说的了,当然,除了那两个把socket封装的类

  • python基础教程之基本数据类型和变量声明介绍

    变量不需要声明 Python的变量不需要声明,你可以直接输入: 复制代码 代码如下: >>>a = 10 那么你的内存里就有了一个变量a, 它的值是10,它的类型是integer (整数). 在此之前你不需要做什么特别的声明,而数据类型是Python自动决定的. 复制代码 代码如下: >>>print a >>>print type(a) 那么会有如下输出: 复制代码 代码如下: 10 <type 'int'> 这里,我们学到一个内置函数t

  • python基础教程之lambda表达式使用方法

    Python中,如果函数体是一个单独的return expression语句,开发者可以选择使用特殊的lambda表达式形式替换该函数: 复制代码 代码如下: lambda parameters: expression lambda表达式相当于函数体为单个return语句的普通函数的匿名函数.请注意,lambda语法并没有使用return关键字.开发者可以在任何可以使用函数引用的位置使用lambda表达式.在开发者想要使用一个简单函数作为参数或者返回值时,使用lambda表达式是很方便的.下面是

  • Python安装使用命令行交互模块pexpect的基础教程

    一.安装 1.安装easy_install工具 wget http://peak.telecommunity.com/dist/ez_setup.py python ez_setup.py 安装easy_install工具(这个脚本会自动去官网搜索下载并安装) python ez_setup.py -U setuptools 升级easy_install工具 2.安装pexpect easy_install Pexpect 测试一下: [root@OMS python]# python Pyth

  • python基础教程项目三之万能的XML

    这个项目的名称与其叫做万能的XML不如叫做自动构建网站,根据一份XML文件,生成对应目录结构的网站,不过只有html还是太过于简单了,如果要是可以连带生成css那就比较强大了.这个有待后续研发,先来研究下怎么html网站结构. 既然是通过XML结构生成网站,那所有的事情都应该由这个XML文件来.先来看下这个XML文件,website.xml: <website> <page name="index" title="Home page"> &l

  • python基础教程项目二之画幅好画

    这是<python基础教程>中的第二个项目,关于python操作PDF. 涉及到的知识点 1.urllib的使用 2.reportlab库的使用 这个例子着实很简单,不过我发现在python里面可以直接在数组[]里面写for循环,真是越用越方便. 下面是代码: from urllib import urlopen from reportlab.graphics.shapes import * from reportlab.graphics.charts.lineplots import Lin

  • python基础教程之popen函数操作其它程序的输入和输出示例

    一.函数介绍 1.1 函数原型: 复制代码 代码如下: #include <stdio.h>FILE *popen(const char *command,const char *open_mode); 1.2 说明 popen函数允许一个程序将另一个程序作为新进程启动,并可以传递数据给它或者通过它接收数据.command字符串是要运行的程序名和相应参数(比如:ls或ls -l),openmode必须是 r 或w.如果是r,被调用程序的输出可以被调用它的程序使用:如果是w,调用程序就可以用fw

  • python基础教程之类class定义使用方法

    面对对象(oop)中的对象,是一个非常重要的知识点,我们可以把它简单看做是数据以及由存取.操作这些数据的方法所组成的一个集合.我们在学习函数(function)之后,知道了如果重用代码,那为什么还要用类来取代函数呢? 类有这样一些的优点 1) .类对象是多态的:也就是多种形态,这意味着我们可以对不同的类对象使用同样的操作方法,而不需要额外写代码. 2).类的封装:封装之后,可以直接调用类的对象,来操作内部的一些类方法,不需要让使用者看到代码工作的细节. 3).类的继承:类可以从其它类或者元类中继

  • python基础教程之数字处理(math)模块详解

    1.math简介 复制代码 代码如下: >>> import math>>>dir(math)          #这句可查看所有函数名列表>>>help(math)         #查看具体定义及函数0原型 2.常用函数 复制代码 代码如下: ceil(x) 取顶floor(x) 取底fabs(x) 取绝对值factorial (x) 阶乘hypot(x,y)  sqrt(x*x+y*y)pow(x,y) x的y次方sqrt(x) 开平方log(x

随机推荐