nntplib — NNTP 协议客户端 — Python 文档

来自菜鸟教程
Python/docs/3.9/library/nntplib
跳转至:导航、​搜索

nntplib — NNTP 协议客户端

源代码: :source:`Lib/nntplib.py`



该模块定义了类 NNTP,它实现了网络新闻传输协议的客户端。 它可用于实现新闻阅读器或海报,或自动化新闻处理器。 它兼容 RFC 3977 以及旧的 RFC 977RFC 2980[ X121X]。

下面是两个如何使用它的小例子。 要列出有关新闻组的一些统计信息并打印最近 10 篇文章的主题:

>>> s = nntplib.NNTP('news.gmane.io')
>>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
>>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)
Group gmane.comp.python.committers has 1096 articles, range 1 to 1096
>>> resp, overviews = s.over((last - 9, last))
>>> for id, over in overviews:
...     print(id, nntplib.decode_header(over['subject']))
...
1087 Re: Commit privileges for Łukasz Langa
1088 Re: 3.2 alpha 2 freeze
1089 Re: 3.2 alpha 2 freeze
1090 Re: Commit privileges for Łukasz Langa
1091 Re: Commit privileges for Łukasz Langa
1092 Updated ssh key
1093 Re: Updated ssh key
1094 Re: Updated ssh key
1095 Hello fellow committers!
1096 Re: Hello fellow committers!
>>> s.quit()
'205 Bye!'

从二进制文件发布文章(假设文章具有有效标题,并且您有权在特定新闻组上发布):

>>> s = nntplib.NNTP('news.gmane.io')
>>> f = open('article.txt', 'rb')
>>> s.post(f)
'240 Article posted successfully.'
>>> s.quit()
'205 Bye!'

模块本身定义了以下类:

class nntplib.NNTP(host, port=119, user=None, password=None, readermode=None, usenetrc=False[, timeout])

返回一个新的 NNTP 对象,表示与运行在主机 主机 上的 NNTP 服务器的连接,监听端口 端口 。 可以为套接字连接指定可选的 timeout。 如果提供了可选的 userpassword,或者 /.netrc 中存在合适的凭据并且可选标志 usenetrc 为真,则 [ X171X] 和 AUTHINFO PASS 命令用于向服务器识别和验证用户。 如果可选标志 readermode 为真,则在执行身份验证之前发送 mode reader 命令。 如果您连接到本地机器上的 NNTP 服务器并打算调用特定于阅读器的命令,例如 group,有时需要阅读器模式。 如果您收到意外的 NNTPPermanentErrors,您可能需要设置 readermodeNNTP 类支持 [X39X]with 语句无条件消耗 OSError 异常并在完成后关闭 NNTP 连接,例如:

>>> from nntplib import NNTP
>>> with NNTP('news.gmane.io') as n:
...     n.group('gmane.comp.python.committers')
... 
('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers')
>>>

在 3.2 版更改:usenetrc 现在默认为 False

在 3.3 版更改:添加了对 with 语句的支持。

在 3.9 版更改: 如果 timeout 参数设置为零,则会引发 ValueError 以防止创建非阻塞套接字。

class nntplib.NNTP_SSL(host, port=563, user=None, password=None, ssl_context=None, readermode=None, usenetrc=False[, timeout])

返回一个新的 NNTP_SSL 对象,表示与运行在主机 主机 上的 NNTP 服务器的加密连接,监听端口 端口NNTP_SSL 对象与 NNTP 对象具有相同的方法。 如果省略 port,则使用端口 563 (NNTPS)。 ssl_context 也是可选的,是一个 SSLContext 对象。 请阅读 安全注意事项 以获得最佳实践。 所有其他参数的行为与 NNTP 相同。

请注意,根据 RFC 4642,不鼓励 SSL-on-563,支持 STARTTLS,如下所述。 但是,有些服务器只支持前者。

3.2 版中的新功能。

3.4 版更改: 该类现在支持使用 ssl.SSLContext.check_hostname服务器名称指示 进行主机名检查(请参阅 ssl.HAS_SNI )。

在 3.9 版更改: 如果 timeout 参数设置为零,则会引发 ValueError 以防止创建非阻塞套接字。

exception nntplib.NNTPError
派生自标准异常 Exception,这是由 nntplib 模块引发的所有异常的基类。 此类的实例具有以下属性:
response
服务器的响应(如果可用),作为 str 对象。
exception nntplib.NNTPReplyError
从服务器收到意外回复时引发异常。
exception nntplib.NNTPTemporaryError
收到 400-499 范围内的响应代码时引发异常。
exception nntplib.NNTPPermanentError
收到 500-599 范围内的响应代码时引发异常。
exception nntplib.NNTPProtocolError
当从服务器收到不以 1-5 范围内的数字开头的回复时引发异常。
exception nntplib.NNTPDataError
响应数据中存在错误时引发异常。

NNTP 对象

连接时,NNTPNNTP_SSL 对象支持以下方法和属性。

属性

NNTP.nntp_version

一个整数,表示服务器支持的 NNTP 协议版本。 实际上,对于广告 RFC 3977 合规性的服务器,这应该是 2,而对于其他服务器,这应该是 1

3.2 版中的新功能。

NNTP.nntp_implementation

描述 NNTP 服务器的软件名称和版本的字符串,如果服务器未通告,则为 None

3.2 版中的新功能。


方法

在几乎所有方法的返回元组中作为第一项返回的 response 是服务器的响应:一个以三位数代码开头的字符串。 如果服务器的响应指示错误,则该方法会引发上述异常之一。

以下许多方法采用可选的仅关键字参数 file。 当提供 file 参数时,它必须是为二进制写入打开的 file object,或要写入的磁盘文件的名称。 然后该方法会将服务器返回的任何数据(响应行和终止点除外)写入文件; 该方法通常返回的任何行、元组或对象列表都将为空。

3.2 版更改: 以下许多方法已被重新设计和修复,这使得它们与 3.1 版本不兼容。


NNTP.quit()
发送 QUIT 命令并关闭连接。 一旦调用了此方法,就不应调用 NNTP 对象的其他方法。
NNTP.getwelcome()
返回服务器发送的欢迎消息以回复初始连接。 (此消息有时包含可能与用户相关的免责声明或帮助信息。)
NNTP.getcapabilities()

返回服务器通告的 RFC 3977 能力,作为 dict 实例映射能力名称到(可能为空)值列表。 在不理解 CAPABILITIES 命令的旧服务器上,将返回一个空字典。

>>> s = NNTP('news.gmane.io')
>>> 'POST' in s.getcapabilities()
True

3.2 版中的新功能。

NNTP.login(user=None, password=None, usenetrc=True)

使用用户名和密码发送 AUTHINFO 命令。 如果 userpasswordNoneusenetrc 为真,则将尽可能使用来自 ~/.netrc 的凭据。

除非故意延迟,登录通常在NNTP对象初始化期间进行,不需要单独调用该函数。 要强制延迟认证,在创建对象时不能设置userpassword,必须设置usenetrc为False。

3.2 版中的新功能。

NNTP.starttls(context=None)

发送 STARTTLS 命令。 这将在 NNTP 连接上启用加密。 context 参数是可选的,应该是一个 ssl.SSLContext 对象。 请阅读 安全注意事项 以获得最佳实践。

请注意,这可能不会在传输身份验证信息后进行,并且在 NNTP 对象初始化期间,如果可能,默认情况下会进行身份验证。 有关抑制此行为的信息,请参阅 NNTP.login()

3.2 版中的新功能。

在 3.4 版更改:该方法现在支持使用 ssl.SSLContext.check_hostnameServer Name Indication 进行主机名检查(请参阅 ssl.HAS_SNI )。

NNTP.newgroups(date, *, file=None)

发送 NEWGROUPS 命令。 date 参数应该是 datetime.datedatetime.datetime 对象。 返回一对 (response, groups),其中 groups 是一个列表,表示自给定 date 以来新的组。 但是,如果提供 file,则 groups 将为空。

>>> from datetime import date, timedelta
>>> resp, groups = s.newgroups(date.today() - timedelta(days=3))
>>> len(groups) 
85
>>> groups[0] 
GroupInfo(group='gmane.network.tor.devel', last='4', first='1', flag='m')
NNTP.newnews(group, date, *, file=None)

发送 NEWNEWS 命令。 这里,group 是组名或 '*'datenewgroups() 具有相同的含义。 返回一对 (response, articles),其中 articles 是消息 ID 列表。

NNTP 服务器管理员经常禁用此命令。

NNTP.list(group_pattern=None, *, file=None)

发送 LISTLIST ACTIVE 命令。 返回一对 (response, list),其中 list 是表示此 NNTP 服务器可用的所有组的元组列表,可选择匹配模式字符串 group_pattern。 每个元组的格式为 (group, last, first, flag),其中 group 是组名,lastfirst 是最后和第一个文章编号,[ X150X]flag 通常采用以下值之一:

  • y:允许本地发帖和同行文章。

  • m:该群组已审核,所有帖子必须获得批准。

  • n:不允许本地发帖,只能发同行文章。

  • j:来自同行的文章被提交到垃圾组。

  • x:无本地发帖,忽略同行文章。

  • =foo.bar:文章改为在foo.bar组中归档。

如果 flag 有另一个值,那么新闻组的状态应该被认为是未知的。

此命令可以返回非常大的结果,尤其是在未指定 group_pattern 的情况下。 最好离线缓存结果,除非您确实需要刷新它们。

3.2 版更改:添加了 group_pattern

NNTP.descriptions(grouppattern)

发送 LIST NEWSGROUPS 命令,其中 grouppatternRFC 3977 中指定的通配符字符串(它本质上与 DOS 或 UNIX shell 通配符相同字符串)。 返回一对 (response, descriptions),其中 descriptions 是将组名称映射到文本描述的字典。

>>> resp, descs = s.descriptions('gmane.comp.python.*')
>>> len(descs) 
295
>>> descs.popitem() 
('gmane.comp.python.bio.general', 'BioPython discussion list (Moderated)')
NNTP.description(group)

获取单个组 的描述。 如果多个组匹配(如果 'group' 是真正的 Wildmat 字符串),则返回第一个匹配项。 如果没有组匹配,则返回一个空字符串。

这省略了来自服务器的响应代码。 如果需要响应代码,请使用 descriptions()

NNTP.group(name)
发送 GROUP 命令,其中 name 是组名。 该组被选为当前组(如果存在)。 返回一个元组 (response, count, first, last, name),其中 count 是组中的(估计)文章数,first 是组中的第一个文章编号,last[ X163X]为组中最后一个货号,name为组名。
NNTP.over(message_spec, *, file=None)

在旧服务器上发送 OVER 命令或 XOVER 命令。 message_spec 可以是表示消息 ID 的字符串,也可以是表示当前组中文章范围的 (first, last) 数字元组,或者表示范围的 (first, None) 元组文章从first到当前组中的最后一篇,或None选择当前组中的当前文章。

返回一对 (response, overviews)overviews 是一个 (article_number, overview) 元组列表,每个 message_spec 选择的文章对应一个。 每个 overview 都是一个字典,项目数相同,但这个数字取决于服务器。 这些项目要么是消息标题(关键是小写的标题名称),要么是元数据项目(关键是元数据名称加上 ":")。 NNTP 规范保证以下项目存在:

  • subjectfromdatemessage-idreferences 标头

  • :bytes 元数据:整个原始文章的字节数(包括标题和正文)

  • :lines 元数据:文章正文的行数

每个项目的值要么是一个字符串,要么是 None(如果不存在)。

当标头值可能包含非 ASCII 字符时,建议对标头值使用 decode_header() 函数:

>>> _, _, first, last, _ = s.group('gmane.comp.python.devel')
>>> resp, overviews = s.over((last, last))
>>> art_num, over = overviews[0]
>>> art_num
117216
>>> list(over.keys())
['xref', 'from', ':lines', ':bytes', 'references', 'date', 'message-id', 'subject']
>>> over['from']
'=?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?= <martin@v.loewis.de>'
>>> nntplib.decode_header(over['from'])
'"Martin v. Löwis" <martin@v.loewis.de>'

3.2 版中的新功能。

NNTP.help(*, file=None)
发送 HELP 命令。 返回一对 (response, list),其中 list 是帮助字符串列表。
NNTP.stat(message_spec=None)

发送 STAT 命令,其中 message_spec 是消息 ID(包含在 '<''>' 中)或当前组中的文章编号。 如果省略 message_specNone,则考虑当前组中的当前文章。 返回一个三元组 (response, number, id),其中 number 是文章编号,id 是消息 ID。

>>> _, _, first, last, _ = s.group('gmane.comp.python.devel')
>>> resp, number, message_id = s.stat(first)
>>> number, message_id
(9099, '<20030112190404.GE29873@epoch.metaslash.com>')
NNTP.next()
发送 NEXT 命令。 返回 stat()
NNTP.last()
发送 LAST 命令。 返回 stat()
NNTP.article(message_spec=None, *, file=None)

发送 ARTICLE 命令,其中 message_specstat() 的含义相同。 返回一个元组 (response, info),其中 info 是一个 namedtuple,具有三个属性 numbermessage_id 和 lines[ X142X](按此顺序)。 number 是群中的文章编号(如果信息不可用则为 0),message_id 为字符串的消息 ID,以及 lines 列表包含原始消息的行(不终止换行符),包括标题和正文。

>>> resp, info = s.article('<20030112190404.GE29873@epoch.metaslash.com>')
>>> info.number
0
>>> info.message_id
'<20030112190404.GE29873@epoch.metaslash.com>'
>>> len(info.lines)
65
>>> info.lines[0]
b'Path: main.gmane.org!not-for-mail'
>>> info.lines[1]
b'From: Neal Norwitz <neal@metaslash.com>'
>>> info.lines[-3:]
[b'There is a patch for 2.3 as well as 2.2.', b'', b'Neal']
NNTP.head(message_spec=None, *, file=None)
article() 相同,但发送 HEAD 命令。 返回(或写入 file)的 lines 将仅包含消息标题,而不包含正文。
NNTP.body(message_spec=None, *, file=None)
article() 相同,但发送 BODY 命令。 返回(或写入 file)的 lines 将仅包含邮件正文,而不包含标题。
NNTP.post(data)

使用 POST 命令发表文章。 data 参数是为二进制读取而打开的 文件对象 ,或任何可迭代的字节对象(代表要发布的文章的原始行)。 它应该代表一篇格式良好的新闻文章,包括所需的标题。 post() 方法自动转义以 . 开头的行并附加终止行。

如果该方法成功,则返回服务器的响应。 如果服务器拒绝发布,则会引发 NNTPReplyError

NNTP.ihave(message_id, data)
发送 IHAVE 命令。 message_id 是要发送到服务器的消息的 id(包含在 '<''>' 中)。 data 参数和返回值与 post() 相同。
NNTP.date()
返回一对 (response, date)date 是一个 datetime 对象,包含服务器的当前日期和时间。
NNTP.slave()
发送 SLAVE 命令。 返回服务器的 响应
NNTP.set_debuglevel(level)
设置实例的调试级别。 这控制打印的调试输出量。 默认值 0 不产生调试输出。 1 的值会产生适量的调试输出,通常每个请求或响应只有一行。 2 或更高的值会产生最大数量的调试输出,记录连接上发送和接收的每一行(包括消息文本)。

以下是 RFC 2980 中定义的可选 NNTP 扩展。 其中一些已被 RFC 3977 中的新命令取代。

NNTP.xhdr(hdr, str, *, file=None)
发送 XHDR 命令。 hdr 参数是标题关键字,例如 'subject'str 参数的格式应为 'first-last',其中 firstlast 是要搜索的第一个和最后一个文章编号。 返回一对 (response, list),其中 list 是对 (id, text) 的列表,其中 id 是商品编号(作为字符串)和 ]text 是该文章请求标题的文本。 如果提供 file 参数,则 XHDR 命令的输出存储在文件中。 如果 file 是一个字符串,那么该方法将打开一个具有该名称的文件,写入然后关闭它。 如果 file 是一个 file object,那么它将开始调用 write() 来存储命令输出的行。 如果提供了 file,则返回的 list 是一个空列表。
NNTP.xover(start, end, *, file=None)
发送 XOVER 命令。 startend 是界定要选择的文章范围的文章编号。 返回值与 over() 相同。 建议改用 over(),因为它会自动使用较新的 OVER 命令(如果可用)。


实用功能

该模块还定义了以下实用程序函数:

nntplib.decode_header(header_str)

解码标头值,取消转义任何转义的非 ASCII 字符。 header_str 必须是一个 str 对象。 返回未转义的值。 建议使用此函数以人类可读的形式显示一些标题:

>>> decode_header("Some subject")
'Some subject'
>>> decode_header("=?ISO-8859-15?Q?D=E9buter_en_Python?=")
'Débuter en Python'
>>> decode_header("Re: =?UTF-8?B?cHJvYmzDqG1lIGRlIG1hdHJpY2U=?=")
'Re: problème de matrice'