nntplib
--- NNTP 協(xié)議客戶端?
源代碼: Lib/nntplib.py
此模塊定義了 NNTP
類來實現(xiàn)網(wǎng)絡新聞傳輸協(xié)議的客戶端。 它可被用于實現(xiàn)一個新聞閱讀或發(fā)布器,或是新聞自動處理程序。 它兼容了 RFC 3977 以及較舊的 RFC 977 和 RFC 2980。
下面是此模塊的兩個簡單用法示例。 列出某個新聞組的一些統(tǒng)計數(shù)據(jù)并打印最近 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!'
要基于一個二進制文件發(fā)布文章 (假定文章包含有效的標頭,并且你有在特定新聞組上發(fā)布內(nèi)容的權限):
>>> 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
對象,代表一個對運行于主機 host,在端口 port 上監(jiān)聽的 NNTP 服務器的連接。 可以為套接字連接指定可選的 timeout。 如果提供了可選的 user 和 password,或者如果在/.netrc
中存在適合的憑證并且可選的旗標 usenetrc 為真值,則會使用AUTHINFO USER
和AUTHINFO PASS
命令在服務器上標識和認證用戶。 如果可選的旗標 readermode 為真值,則會在執(zhí)行認證之前發(fā)送mode reader
命令。 在某些時候如果你是連接本地機器上的 NNTP 服務器并且想要調(diào)用讀取者專屬命令如group
那么還必須使用讀取者模式。 如果你收到預料之外的NNTPPermanentError
,你可能需要設置 readermode。NNTP
類支持使用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') >>>
引發(fā)一個 審計事件
nntplib.connect
,附帶參數(shù)self
,host
,port
。引發(fā)一個 審計事件
nntplib.putline
,附帶參數(shù)self
,line
。在 3.2 版更改: usenetrc 現(xiàn)在默認為
False
。在 3.3 版更改: 添加了對
with
語句的支持。在 3.9 版更改: 如果 timeout 參數(shù)設置為 0,創(chuàng)建非阻塞套接字時,它將引發(fā)
ValueError
來阻止該操作。
- class nntplib.NNTP_SSL(host, port=563, user=None, password=None, ssl_context=None, readermode=None, usenetrc=False[, timeout])?
返回一個新的
NNTP_SSL
對象,代表一個對運行于主機 host,在端口 port 上監(jiān)聽的 NNTP 服務器的連接。NNTP_SSL
對象具有與NNTP
對象相同的方法。 如果 port 被省略,則會使用端口 563 (NNTPS)。 ssl_context 也是可選的,且為一個SSLContext
對象。 請閱讀 安全考量 來了解最佳實踐。 所有其他形參的行為都與NNTP
的相同。請注意 RFC 4642 不再推薦使用 563 端口的 SSL,建議改用下文描述的 STARTTLS。 但是,某些服務器只支持前者。
引發(fā)一個 審計事件
nntplib.connect
,附帶參數(shù)self
,host
,port
。引發(fā)一個 審計事件
nntplib.putline
,附帶參數(shù)self
,line
。3.2 新版功能.
在 3.4 版更改: 本類現(xiàn)在支持使用
ssl.SSLContext.check_hostname
和 服務器名稱指示 (參閱ssl.HAS_SNI
)進行主機名檢查。在 3.9 版更改: 如果 timeout 參數(shù)設置為 0,創(chuàng)建非阻塞套接字時,它將引發(fā)
ValueError
來阻止該操作。
- exception nntplib.NNTPReplyError?
從服務器收到意外答復時,將引發(fā)本異常。
- exception nntplib.NNTPTemporaryError?
收到 400--499 范圍內(nèi)的響應代碼時所引發(fā)的異常。
- exception nntplib.NNTPPermanentError?
收到 500--599 范圍內(nèi)的響應代碼時所引發(fā)的異常。
- exception nntplib.NNTPProtocolError?
當從服務器收到不是以數(shù)字 1--5 開頭的答復時所引發(fā)的異常。
- exception nntplib.NNTPDataError?
當響應數(shù)據(jù)中存在錯誤時所引發(fā)的異常。
NNTP 對象?
當連接時,NNTP
和 NNTP_SSL
對象支持以下方法和屬性。
屬性?
方法?
作為幾乎全部方法所返回元組的第一項返回的 response 是服務器的響應:以三位數(shù)字代碼打頭的字符串。 如果服務器的響應是提示錯誤,則方法將引發(fā)上述異常之一。
以下方法中許多都接受一個可選的僅限關鍵字參數(shù) file。 當提供了 file 參數(shù)時,它必須為打開用于二進制寫入的 file object,或要寫入的磁盤文件名稱。 此類方法隨后將把服務器返回的任意數(shù)據(jù)(除了響應行和表示結束的點號)寫入到文件中;此類方法通常返回的任何行列表、元組或?qū)ο蠖紝榭罩怠?/p>
在 3.2 版更改: 以下方法中許多都已被重寫和修正,這使得它們不再與 3.1 中的同名方法相兼容。
- NNTP.quit()?
發(fā)送
QUIT
命令并關閉連接。 一旦此方法被調(diào)用,NNTP 對象的其他方法都不應再被調(diào)用。
- NNTP.getwelcome()?
返回服務器發(fā)送的歡迎消息,作為連接開始的回復。(該消息有時包含與用戶有關的免責聲明或幫助信息。)
- 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)?
發(fā)送
AUTHINFO
命令并附帶用戶名和密碼。 如果 user 和 password 為None
且 usenetrc 為真值,則會在可能的情況下使用來自~/.netrc
的憑證。除非被有意延遲,登錄操作通常會在
NNTP
對象初始化期間被執(zhí)行因而沒有必要單獨調(diào)用此函數(shù)。 要強制延遲驗證,你在創(chuàng)建該對象時不能設置 user 或 password,并必須將 usenetrc 設為 False。3.2 新版功能.
- NNTP.starttls(context=None)?
發(fā)送
STARTTLS
命令。 這將在 NNTP 連接上啟用加密。 context 參數(shù)是可選的且應為ssl.SSLContext
對象。 請閱讀 安全考量 了解最佳實踐。請注意此操作可能不會在傳輸驗證信息之后立即完成,只要有可能驗證默認會在
NNTP
對象初始化期間發(fā)生。 請參閱NNTP.login()
了解有關如何屏蔽此行為的信息。3.2 新版功能.
在 3.4 版更改: 此方法現(xiàn)在支持使用
ssl.SSLContext.check_hostname
和 服務器名稱指示 (參見ssl.HAS_SNI
) 進行主機名檢查。
- NNTP.newgroups(date, *, file=None)?
發(fā)送
NEWGROUPS
命令。 date 參數(shù)應為datetime.date
或datetime.datetime
對象。 返回一個(response, groups)
對,其中 groups 是代表給定i 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)?
發(fā)送
NEWNEWS
命令。 這里,group 是新聞組名稱或為'*'
,而 date 與newgroups()
中的含義相同。 返回一個(response, articles)
對,其中 articles 為消息 ID 列表。此命令經(jīng)常會被 NNTP 服務器管理員禁用。
- NNTP.list(group_pattern=None, *, file=None)?
發(fā)送
LIST
或LIST ACTIVE
命令。 返回一個(response, list)
對,其中 list 是代表此 NNTP 服務器上所有可用新聞組的元組列表,并可選擇匹配模式字符串 group_pattern。 每個元組的形式為(group, last, first, flag)
,其中 group 為新聞組名稱,last 和 first 是最后一個和第一個文章的編號,而 flag 通常為下列值之一:y
: 允許來自組員的本地發(fā)帖和文章。m
: 新聞組受到管制因而所有發(fā)帖必須經(jīng)過審核。n
: 不允許本地發(fā)帖,只允許來自組員的文章。j
: 來自組員的文章會被轉(zhuǎn)入垃圾分組。x
: 不允許本地發(fā)帖,而來自組員的文章會被忽略。=foo.bar
: 文章會被轉(zhuǎn)入foo.bar
分組。
如果 flag 具有其他值,則新聞組的狀態(tài)應當被視為未知。
此命令可能返回非常龐大的結果,特別是當未指明 group_pattern 的時候。 最好是離線緩存其結果,除非你確實需要刷新它們。
在 3.2 版更改: 增加了 group_pattern。
- NNTP.descriptions(grouppattern)?
發(fā)送
LIST NEWSGROUPS
命令,其中 grouppattern 為 RFC 3977 中規(guī)定的 wildmat 字符串(它實際上與 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 的描述。 如果匹配到一個以上的新聞組(如果 'group' 是一個真實的 wildmat 字符串),則返回第一個匹配結果。 如果未匹配到任何新聞組,則返回空字符串。
此方法略去了來自服務器的響應代碼。 如果需要響應代碼,請使用
descriptions()
。
- NNTP.group(name)?
發(fā)送
GROUP
命令,其中 name 為新聞組名稱。 該新聞組如果存在,則會被選定為當前新聞組。 返回一個元組(response, count, first, last, name)
,其中 count 是該新聞組中(估計的)文章數(shù)量,first 是新聞組中第一篇文章的編號,last 是新聞組中最后一篇文章的編號,而 name 是新聞組名稱。
- NNTP.over(message_spec, *, file=None)?
發(fā)送
OVER
命令,或是舊式服務器上的XOVER
命令。 message_spec 可以是表示消息 ID 的字符串,或是指明當前新聞組內(nèi)文章范圍的數(shù)字元組(first, last)
,或是指明當前新聞組內(nèi)從(first, None)
first 到最后一篇文章的元組,或者為None
表示選定當前新聞組內(nèi)的當前文章。返回一個
(response, overviews)
對。 其中 overviews 是一個包含(article_number, overview)
元組的列表,每個元組對應 message_spec 所選定的一篇文章。 每個 overview 則是包含同樣數(shù)量條目的字典,但具體數(shù)量取決于服務器。 這些條目或是為消息標頭(對應鍵為小寫的標頭名稱)或是為 metadata 項(對應鍵為以":"
打頭的 metadata 名稱)。 以下條目會由 NNTP 規(guī)范描述來確保提供:subject
,from
,date
,message-id
和references
標頭:bytes
metadata: 整個原始文章數(shù)據(jù)的字節(jié)數(shù)(包括標頭和消息體):lines
metadata: 文章消息體的行數(shù)
每個條目的值或者為字符串,或者在沒有值時為
None
。建議在標頭值可能包含非 ASCII 字符的時候?qū)ζ涫褂?
decode_header()
函數(shù):>>> _, _, 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)?
發(fā)送
HELP
命令。 返回一個(response, list)
對,其中 list 為幫助字符串列表。
- NNTP.stat(message_spec=None)?
發(fā)送
STAT
命令,其中 message_spec 為消息 ID (包裹在'<'
和'>'
中) 或者當前新聞組中的文章編號。 如果 message_spec 被省略或為None
,則會選擇當前新聞組中的當前文章。 反回一個三元組(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.article(message_spec=None, *, file=None)?
發(fā)送
ARTICLE
命令,其中 message_spec 的含義與stat()
中的相同。 返回一個元組(response, info)
,其中 info 是一個namedtuple
,包含三個屬性 number, message_id 和 lines (按此順序)。 number 是新聞組中的文章數(shù)量 (或者如果該信息不可用則為 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()
類似,但會發(fā)送HEAD
命令。 返回的 lines (或?qū)懭氲?file) 將只包含消息標頭,不包含消息體。
- NNTP.body(message_spec=None, *, file=None)?
與
article()
類似,但會發(fā)送BODY
命令。 返回的 lines (或?qū)懭氲?file) 將只包含消息體,不包含標頭。
- NNTP.post(data)?
使用
POST
命令發(fā)布文章。 data 參數(shù)是以二進制讀取模式打開的 file object,或是任意包含字節(jié)串對象的可迭代對象 (表示要發(fā)布的文章的原始行數(shù)據(jù))。 它應當代表一篇適當格式的新聞組文章,包含所需的標頭。post()
方法會自動對以.
打頭的行數(shù)據(jù)進行轉(zhuǎn)義并添加結束行。如果此方法執(zhí)行成功,將返回服務器的響應。 如果服務器拒絕響應,則會引發(fā)
NNTPReplyError
。
- NNTP.ihave(message_id, data)?
發(fā)送
IHAVE
命令。 message_id 為要發(fā)給服務器的消息 ID (包裹在'<'
和'>'
中)。 data 形參和返回值與post()
的一致。
- NNTP.slave()?
發(fā)送
SLAVE
命令。 返回服務器的 響應。
- NNTP.set_debuglevel(level)?
設置實例的調(diào)試級別。 它控制著打印調(diào)試輸出信息的數(shù)量。 默認值
0
不產(chǎn)生調(diào)試輸出。 值1
產(chǎn)生中等數(shù)量的調(diào)試輸出,通常每個請求或響應各產(chǎn)生一行。 大于等于2
的值產(chǎn)生最多的調(diào)試輸出,在連接上發(fā)送和接收的每一行信息都會被記錄下來(包括消息文本)。
以下是在 RFC 2980 中定義的可選 NNTP 擴展。 其中一些已被 RFC 3977 中的新命令所取代。
- NNTP.xhdr(hdr, str, *, file=None)?
發(fā)送
XHDR
命令。 hdr 參數(shù)是標頭關鍵字,例如'subject'
。 str 參數(shù)的形式應為'first-last'
,其中 first 和 last 是要搜索的首篇和末篇文章編號。 返回一個(response, list)
對,其中 list 是(id, text)
對的列表,其中 id 是文章編號(字符串類型)而 text 是該文章的請求標頭。 如果提供了 file 形參,則XHDR
命令的輸出會保存到文件中。 如果 file 為字符串,則此方法將打開指定名稱的文件,向其寫入內(nèi)容并將其關閉。 如果 file 為 file object,則將在該文件對象上調(diào)用write()
方法來保存命令所輸出的行信息。 如果提供了 file,則返回的 list 將為空列表。
工具函數(shù)?
這個模塊還定義了下列工具函數(shù):
- nntplib.decode_header(header_str)?
解碼標頭值,恢復任何被轉(zhuǎn)義的非 ASCII 字符。 header_str 必須為
str
對象。 將返回被恢復的值。 推薦使用此函數(shù)來以人類可讀的形式顯示某些標頭:>>> 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'