4. Python脚本学习实战笔记四 新闻聚合

4. Python脚本学习实战笔记四 新闻聚合

                  本篇名言:“人言纷杂,保持自我;工作勤奋,娱乐适度;对待朋友,不玩心术;处理事务,不躁不怒;生活讲究,量入为出;知足常乐,一生幸福!”

                  接下来学习网络相关的知识。如题目标识一般和新闻相关。所以必须学习网络新闻组传输协议(NNTP ,Network News Transfer Protocol).

                  NNTP服务器的主网络称为Usenet.Usenet是世界性的新闻组网络系统,建立于1980年。大部分互联网在一定程度上是基于这种古老的技术。NNTP使用TCP端口号119。本次要实现自定义新闻收集模块可以替代一些社交网络的Web API.

1.  需求

l  程序从不同的来源处收集新闻

l  用户可以添加新闻来源

l  程序将编译好的新闻报告分派出多个不同格式的目标

l  程序可以轻松添加新的目标

 

2.  工具和准备

本次只需要使用标准块模块即可,包括urllib,nntplib以及time 模块。

此外需要寻找一个新闻组,蛤蟆使用的新闻组是:

news.newsfan.net 

(新帆新闻组是一个在中国大陆免费对公共网络开放使用本地化语言命名组名的新闻组。新帆新闻组不同于互相转信同步信息的Usenet上的新闻组,它在讨论分组中一律使用简体中文。)

NNTP服务器需要支持NEWNEWS命令。

fromnntplib import NNTP

fromtime 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.newsfan.net'

group = 'comp.lang.python'

server = NNTP(servername)

ids = server.newnews(group, date,hour)[1]

 

3.  初次实现

初次实现只需将从NNTP服务器上面下载的新闻信息打印到标准输出中即可。

需要3个方法:

1、  newnews方法:返回在给定日期时间之后的文章

2、  head方法:提供关于文章的各种信息

3、  body方法:提供文章的正文文本。

具体实现代码如下:

fromnntplib import NNTP

fromtime import strftime,time, localtime

 

day = 24 * 60 * 60# Number of seconds in one day

 

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'

server = NNTP(servername)

 

ids = server.newnews(group, date,hour)[1]

 

 

forid in ids:

   head = server.head(id)[3]

   for line in head:

        if line.lower().startswith('subject:'):

            subject = line[9:]

            break

 

   body = server.body(id)[3]

 

   print subject

   print'-'*len(subject)

   print'\n'.join(body)

 

server.quit()

 

 

由于新闻组服务器可能不同,所以该代码可能执行报错

如下:

socket.error:[Errno 10060]

4.  重构

在3中可能执行失败,但是没关系重要的是思路和实现的过程。

                  初次实现不够灵活,需要进行重构。重构的时候利用创建类和方法的形式来增加结构和抽象,表示代码的各个部分。

                  一个NewsAgent类,从新闻来源获取新闻项目并且发布到新闻目标的对象。

                  一个NewItem类,包括标题和主体文本的简单新闻项目。

                  一个NNTPSource类,从NNTP组中获取新闻项目的新闻来源。

                  一个SimpleWebSource类,使用正则表达式从网页中提取新闻项目的新闻来源。

                  一个PlainDestination类,将所有新闻项目格式化为纯文本的新闻目标类。

                  一个HTMLDestination类,将所有新闻项目格式化为HTML的目标类。
主程序上一个runDefaultSetup函数。

初始化一个NewAgent对象。

通过SimpleWebSource类,NNTPSource类获取新闻的源,然后增加输出目标,最后发布新闻到目标,结束,具体如下。

                  重构主要是对类的重新架设。

5.  交付

fromnntplib import NNTP

fromtime import strftime,time, localtime

fromemail importmessage_from_string

fromurllib import urlopen

importtextwrap

importre

 

day = 24 * 60 * 60# Number of seconds in one day

 

def wrap(string,max=70):

   """

    Wraps a string to a maximum line width.

    """

 

   return'\n'.join(textwrap.wrap(string)) + '\n'

 

class NewsAgent:

   """

    An object that can distribute news itemsfrom news

    sources to news destinations.

    """

   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):

        """

        Retrieve all news items from allsources, and

        Distribute them to all destinations.

        """

        items = []

        for source in self.sources:

            items.extend(source.getItems())

        for dest in self.destinations:

            dest.receiveItems(items)

 

class NewsItem:

   """

    A simple news item consisting of a titleand a body text.

    """

   def __init__(self,title, body):

        self.title = title

        self.body = body

 

class NNTPSource:

   """

    A news source that retrieves news itemsfrom an NNTP group.

    """

   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:

   """

    A news source that extracts news items froma Web page using

    regular expressions.

    """

   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 inzip(titles, bodies):

            yield NewsItem(title, wrap(body))

 

class PlainDestination:

   """

    A news destination that formats all itsnews items as

    plain text.

    """

   def receiveItems(self,items):

        for item in items:

            print item.title

            print'-'*len(item.title)

            print item.body

 

 

class HTMLDestination:

   """

    A news destination that formats all itsnews items

    as HTML.

    """

   def __init__(self,filename):

        self.filename = filename

 

   def receiveItems(self,items):

 

        out = open(self.filename, 'w')

        print >> out, """

        <html>

          <head>

            <title>Today'sNews</title>

          </head>

          <body>

          <h1>Today's News</h1>

        """

 

        print >> out, '<ul>'

        id = 0

        for item in items:

            id += 1

            print >> out, '  <li><a href="#%i">%s</a></li>' % (id, item.title)

        print >> out, '</ul>'

 

        id = 0

        for item in items:

            id += 1

            print >> out, '<h2><aname="%i">%s</a></h2>' %(id, item.title)

            print >> out, '<pre>%s</pre>' % item.body

 

        print >> out, """

          </body>

        </html>

        """

 

def runDefaultSetup():

   """

    A default setup of sources and destination.Modify to taste.

    """

   agent = NewsAgent()

 

 

   # A SimpleWebSource that retrieves news from the

   # BBC news site:

   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)

 

   # An NNTPSource that retrieves news fromcomp.lang.python.announce:

   clpa_server = 'news.foo.bar'# Insert real server name

   clpa_group = 'comp.lang.python.announce'

   clpa_window = 1

   clpa = NNTPSource(clpa_server, clpa_group, clpa_window)

 

   agent.addSource(clpa)

 

   # Add plain text destination and an HTMLdestination:

   agent.addDestination(PlainDestination())

   agent.addDestination(HTMLDestination('news.html'))

 

   # Distribute the news items:

   agent.distribute()

 

if __name__ == '__main__': runDefaultSetup()

 

 

6.  新闻组相关

·      comp.*- 关于计算机的相关话题。

·      news.*- 关于Usenet本身的讨论。

·      sci.*- 关于科学方面的讨论。

·      humanities.*- 关于人文学科文学哲学等等)的讨论。

·      rec.*- 关于娱乐活动的讨论(游戏、爱好等等)。

·      soc.*- 关于社会话题、社会文化的讨论。

·      talk.*- 关于社会及宗教热点话题的讨论。

·      misc.*- 其他无法归入现有层级的讨论。

·      alt.*- 无法归于其他类别或不愿归入其他类别的话题。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值