4. Python脚本学习实战笔记四 新闻聚合
2017-11-12 10:11
387 查看
4. Python脚本学习实战笔记四 新闻聚合
本篇名言:“人言纷杂,保持自我;工作勤奋,娱乐适度;对待朋友,不玩心术;处理事务,不躁不怒;生活讲究,量入为出;知足常乐,一生幸福!”
接下来学习网络相关的知识。如题目标识一般和新闻相关。所以必须学习网络新闻组传输协议(NNTP ,Network News Transfer Protocol).
NNTP服务器的主网络称为Usenet.Usenet是世界性的新闻组网络系统,建立于1980年。大部分互联网在一定程度上是基于这种古老的技术。NNTP使用TCP端口号119。本次要实现自定义新闻收集模块可以替代一些社交网络的Web API.
l 用户可以添加新闻来源
l 程序将编译好的新闻报告分派出多个不同格式的目标
l 程序可以轻松添加新的目标
此外需要寻找一个新闻组,蛤蟆使用的新闻组是:
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个方法:
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]
初次实现不够灵活,需要进行重构。重构的时候利用创建类和方法的形式来增加结构和抽象,表示代码的各个部分。
一个NewsAgent类,从新闻来源获取新闻项目并且发布到新闻目标的对象。
一个NewItem类,包括标题和主体文本的简单新闻项目。
一个NNTPSource类,从NNTP组中获取新闻项目的新闻来源。
一个SimpleWebSource类,使用正则表达式从网页中提取新闻项目的新闻来源。
一个PlainDestination类,将所有新闻项目格式化为纯文本的新闻目标类。
一个HTMLDestination类,将所有新闻项目格式化为HTML的目标类。
主程序上一个runDefaultSetup函数。
初始化一个NewAgent对象。
通过SimpleWebSource类,NNTPSource类获取新闻的源,然后增加输出目标,最后发布新闻到目标,结束,具体如下。
重构主要是对类的重新架设。
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()
· news.*- 关于Usenet本身的讨论。
· sci.*- 关于科学方面的讨论。
· humanities.*- 关于人文学科(文学、哲学等等)的讨论。
· rec.*- 关于娱乐活动的讨论(游戏、爱好等等)。
· soc.*- 关于社会话题、社会文化的讨论。
· talk.*- 关于社会及宗教热点话题的讨论。
· misc.*- 其他无法归入现有层级的讨论。
· alt.*- 无法归于其他类别或不愿归入其他类别的话题。
本篇名言:“人言纷杂,保持自我;工作勤奋,娱乐适度;对待朋友,不玩心术;处理事务,不躁不怒;生活讲究,量入为出;知足常乐,一生幸福!”
接下来学习网络相关的知识。如题目标识一般和新闻相关。所以必须学习网络新闻组传输协议(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. 交付
fromnntplibimport 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.*- 无法归于其他类别或不愿归入其他类别的话题。
相关文章推荐
- 8. Python脚本学习实战笔记八 使用XML-RPC进行文件共享
- 9. Python脚本学习实战笔记九 文件共享GUI实现
- 1.Python脚本学习实战笔记一 即时标记
- 2. Python脚本学习实战笔记二 分析提取数据成图
- 3. Python脚本学习实战笔记三 主流的XML
- 5. Python脚本学习实战笔记五 茶话会
- 7. Python脚本学习实战笔记七 电子公告板
- Selenium2 Python 自动化测试实战学习笔记(四)
- python 学习笔记 12 -- 写一个脚本获取城市天气信息
- Selenium2 Python 自动化测试实战学习笔记(三)
- Selenium2 Python 自动化测试实战学习笔记(四)
- Selenium2 Python 自动化测试实战学习笔记(九)
- python学习笔记:在python文件中如何调用其它python脚本文件
- Selenium2 Python 自动化测试实战学习笔记(二)
- 2. Python脚本学习笔记二基本命令畅玩
- selenium+python:脚本学习笔记(三)
- 16. Python脚本学习笔记十六生成器
- 28. Python脚本学习笔记二十八代码检测和分析
- Selenium2 Python 自动化测试实战学习笔记(五)
- 17. Python脚本学习笔记十七Python的八皇后问题