您的位置:首页 > 编程语言 > Python开发

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

2017-11-12 10:11 387 查看
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.*- 无法归于其他类别或不愿归入其他类别的话题。

 

 

 

 

 

 

 

 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: