网络新闻
什么是Usenet 与新闻组
usenet新闻系统是一个全球存档的‘’电子公告版”。各种主题新闻组一应俱全,从诗歌到政治,从自然语言学到计算机语言,从软件到硬件,从种植到烹饪、招聘/应聘、音乐、 魔术、相亲等。新闻组可以面向全球,也可以只面向某个特定区域。
每个系统是一个由大量计算机组成的全球网络,计算机之间共享Usenet上的帖子,如果某个用户发了一个帖子到本地的 Usenet 计算机上,这个帖子会被传播到其他相连 的计算机上,再由这些计算机传到与它们相连的计算机上,直到这个帖子传播到了全世界, 每个人都收到这个帖子为止。帖子在 Usenet 上的存活时间是有限的,这个时间可以由 Usenet 系统管理员来指定,也可以为帖子指定一个过期的日期/时间。
每个系统都有一个已“订阅”的新闻组列表,系统只接收感兴趣的新闻组里的帖子,而不是 接收服务器上所有新闻组的帖子。Usenet 新闻组的内容由提供者安排,很多服务都是公开的。但 也有一些服务只允许特定用户使用,例如付费用户、特定大学的学生等。Usenet 系统管理员可能 会进行一些设置来要求用户输入用户名和密码,管理员也可以设置是否只能上传或只能下载
网络新闻传输协议—NNTP
用户使用网络新闻传输协议(NNTP)在新闻组中下载或发表帖子。该协议由Brain Kantor (加州大学圣地亚哥分校)和 Phil Lapsley(加州大学伯克利分校)创建,于 1986 年 2 月公布。其后在 2000 年 10 月公布的 RFC 2980 中对该协议进行了更新。
作为客户端/服务器架构的另一个例子,NNTP 与 FTP 的操作方式相似,但更简单。在 FTP 中,登录、传输数据和控制需要使用不同的端口,而 NNTP 只使用一个标准端口 119 来 通信。用户向服务器发送一个请求,服务器就做出相应的响应,如图 所示。
FTP传输协议 如下
NNTP传输协议如下
Python 和 NNTP
NNTP大致的工作流程如下;
- 连接到服务器。
- 登陆(根据需求)。
- 发出服务请求。
- 退出
NNTP类方法
这里列举出一些常用的方法,详细内容建议参考Python库手册
客户端程序 NNTP 示例
import nntplib
import socket
HOST = 'your.nntp.server'
GRNM = 'comp.lang.python'
USER = 'wesley'
PASS = "you'llNeverGuess"
def main():
try:
n = nntplib.NNTP(HOST) #, user=USER, password=PASS)
except socket.gaierror as e:
print ('ERROR: cannot reach host "%s"' % HOST)
print (' ("%s")' % eval(str(e))[1])
return
except nntplib.NNTPPermanentError as e:
print ('ERROR: access denied on "%s"' % HOST)
print (' ("%s")' % str(e))
return
print ('*** Connected to host "%s"' % HOST)
try:
rsp, ct, fst, lst, grp = n.group(GRNM)
except nntplib.NNTPTemporaryError as e:
print ('ERROR: cannot connect to group "%s"' % GRNM)
print (' ("%s")' % str(e))
print (' Server may require authentication')
print (' Uncomment/edit login line above')
n.quit()
return
except nntplib.NNTPTemporaryError as e:
print ('ERROR: group "%s" unavailable' % GRNM)
print (' ("%s")' % str(e))
n.quit()
return
print ('*** Found newsgroup "%s"' % GRNM)
rng = '%s-%s' % (lst, lst)
rsp, frm = n.xhdr('from', rng)
rsp, sub = n.xhdr('subject', rng)
rsp, dat = n.xhdr('date', rng)
print ('''*** Found last article (#%s):\n
From: %s
Subject: %s
Date: %s
'''% (lst, frm[0][1], sub[0][1], dat[0][1]))
rsp, anum, mid, data = n.body(lst)
displayFirst20(data)
n.quit()
def displayFirst20(data):
print ('*** First (<= 20) meaningful lines:\n')
count = 0
lines = (line.rstrip() for line in data)
lastBlank = True
for line in lines:
if line:
lower = line.lower()
if (lower.startswith('>') and not \
lower.startswith('>>>')) or \
lower.startswith('|') or \
lower.startswith('in article') or \
lower.endswith('writes:') or \
lower.endswith('wrote:'):
continue
if not lastBlank or (lastBlank and line):
print (' %s' % line)
if line:
count += 1
lastBlank = False
else:
lastBlank = True
if count == 20:
break
if __name__ == '__main__':
main()