nntplib.md
1> **Источник:** https://python-all.ru/3.2/library/nntplib.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 20.14. [`nntplib`](https://python-all.ru/3.2/library/nntplib.html#module-nntplib) – клиент протокола NNTP89**Исходный код:** [Lib/nntplib.py](https://python-all.ru/src/3.2/Lib/nntplib.py)1011---1213Этот модуль определяет класс [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP), который реализует клиентскую часть протокола передачи сетевых новостей (Network News Transfer Protocol). Его можно использовать для создания программы чтения новостей, отправки новостей или автоматизированной обработки новостей. Он совместим с [**RFC 3977**](https://python-all.ru/3.2/library/nntplib.html), а также с более старыми [**RFC 977**](https://python-all.ru/3.2/library/nntplib.html) и [**RFC 2980**](https://python-all.ru/3.2/library/nntplib.html).1415Вот два небольших примера использования. Чтобы вывести статистику по группе новостей и напечатать темы последних 10 статей:1617```python18>>> s = nntplib.NNTP('news.gmane.org')19>>> resp, count, first, last, name = s.group('gmane.comp.python.committers')20>>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)21Group gmane.comp.python.committers has 1096 articles, range 1 to 109622>>> resp, overviews = s.over((last - 9, last))23>>> for id, over in overviews:24... print(id, nntplib.decode_header(over['subject']))25...261087 Re: Commit privileges for Łukasz Langa271088 Re: 3.2 alpha 2 freeze281089 Re: 3.2 alpha 2 freeze291090 Re: Commit privileges for Łukasz Langa301091 Re: Commit privileges for Łukasz Langa311092 Updated ssh key321093 Re: Updated ssh key331094 Re: Updated ssh key341095 Hello fellow committers!351096 Re: Hello fellow committers!36>>> s.quit()37'205 Bye!'38```3940Чтобы опубликовать статью из двоичного файла (предполагается, что статья содержит корректные заголовки и у вас есть права на публикацию в данной группе новостей):4142```python43>>> s = nntplib.NNTP('news.gmane.org')44>>> f = open('article.txt', 'rb')45>>> s.post(f)46'240 Article posted successfully.'47>>> s.quit()48'205 Bye!'49```5051Сам модуль определяет следующие классы:5253#### `class nntplib.NNTP(host, port=119, user=None, password=None, readermode=None, usenetrc=False[, timeout])`5455Возвращает новый объект [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP), представляющий соединение с сервером NNTP, работающим на узле *host*, прослушивающем порт *port*. Для сокетного соединения можно указать необязательный таймаут *timeout*. Если указаны необязательные *user* и *password*, или если подходящие учётные данные есть в `/.netrc` и необязательный флаг *usenetrc* имеет значение true, используются команды `AUTHINFO USER` и `AUTHINFO PASS` для идентификации и аутентификации пользователя на сервере. Если необязательный флаг *readermode* имеет значение true, перед аутентификацией отправляется команда `mode reader`. Режим чтения иногда необходим при подключении к серверу NNTP на локальной машине, если планируется вызывать команды, специфичные для режима чтения, такие как `group`. Если возникают неожиданные ошибки [`NNTPPermanentError`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTPPermanentError), возможно, потребуется установить *readermode*.5657Изменено в версии 3.2: *usenetrc* теперь по умолчанию равно False.5859#### `class nntplib.NNTP_SSL(host, port=563, user=None, password=None, ssl_context=None, readermode=None, usenetrc=False[, timeout])`6061Возвращает новый объект [`NNTP_SSL`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP_SSL), представляющий зашифрованное соединение с NNTP-сервером, работающим на узле *host*, прослушивающим порт *port*. Объекты [`NNTP_SSL`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP_SSL) имеют те же методы, что и объекты [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP). Если *port* опущен, используется порт 563 (NNTPS). *ssl\_context* также необязателен и представляет собой объект [`SSLContext`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext). Все остальные параметры ведут себя так же, как для [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP).6263Обратите внимание, что SSL на порту 563 не рекомендуется согласно [**RFC 4642**](https://python-all.ru/3.2/library/nntplib.html), вместо него следует использовать STARTTLS, как описано ниже. Однако некоторые серверы поддерживают только первый вариант.6465Новое в версии 3.2.6667#### `exception nntplib.NNTPError`6869Производный от стандартного исключения [`Exception`](https://python-all.ru/3.2/library/exceptions.html#Exception), это базовый класс для всех исключений, возбуждаемых модулем [`nntplib`](https://python-all.ru/3.2/library/nntplib.html#module-nntplib). Экземпляры этого класса имеют следующий атрибут:7071#### `response`7273Ответ сервера, если доступен, в виде объекта [`str`](https://python-all.ru/3.2/library/functions.html#str).7475#### `exception nntplib.NNTPReplyError`7677Исключение, возникающее при получении неожиданного ответа от сервера.7879#### `exception nntplib.NNTPTemporaryError`8081Исключение возбуждается, когда получен код ответа в диапазоне 400–499.8283#### `exception nntplib.NNTPPermanentError`8485Исключение возбуждается, когда получен код ответа в диапазоне 500–599.8687#### `exception nntplib.NNTPProtocolError`8889Исключение возбуждается, когда от сервера получен ответ, который не начинается с цифры в диапазоне 1–5.9091#### `exception nntplib.NNTPDataError`9293Исключение возбуждается при наличии ошибки в данных ответа.9495## 20.14.1. Объекты NNTP9697При подключении объекты [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP) и [`NNTP_SSL`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP_SSL) поддерживают следующие методы и атрибуты.9899### 20.14.1.1. Атрибуты100101#### `NNTP.nntp_version`102103Целое число, представляющее версию протокола NNTP, поддерживаемую сервером. На практике должно быть равно `2` для серверов, заявляющих о соответствии [**RFC 3977**](https://python-all.ru/3.2/library/nntplib.html), и `1` для остальных.104105Новое в версии 3.2.106107#### `NNTP.nntp_implementation`108109Строка, описывающая название программного обеспечения и версию сервера NNTP, или [`None`](https://python-all.ru/3.2/library/constants.html#None), если сервер не сообщил эту информацию.110111Новое в версии 3.2.112113### 20.14.1.2. Методы114115*Ответ*, возвращаемый в качестве первого элемента кортежа результатов почти всех методов, – это ответ сервера: строка, начинающаяся с трёхзначного кода. Если ответ сервера указывает на ошибку, метод возбуждает одно из перечисленных выше исключений.116117Многие из следующих методов принимают необязательный аргумент, передаваемый только по ключу, *file*. Когда аргумент *file* указан, он должен быть либо [*файловый объект*](https://python-all.ru/3.2/glossary.html#term-file-object), открытым для бинарной записи, либо именем файла на диске для записи. В этом случае метод будет записывать все данные, возвращаемые сервером (за исключением строки ответа и завершающей точки), в файл; любой список строк, кортежей или объектов, который метод обычно возвращает, будет пуст.118119Изменено в версии 3.2: Многие из следующих методов были переработаны и исправлены, что делает их несовместимыми с аналогами из версии 3.1.120121#### `NNTP.quit()`122123Отправляет команду `QUIT` и закрывает соединение. После вызова этого метода не следует вызывать другие методы объекта NNTP.124125#### `NNTP.getwelcome()`126127Возвращает приветственное сообщение, отправленное сервером в ответ на начальное подключение. (Это сообщение иногда содержит отказ от ответственности или справочную информацию, которая может быть полезна пользователю.)128129#### `NNTP.getcapabilities()`130131Return the [**RFC 3977**](https://python-all.ru/3.2/library/nntplib.html) capabilities advertised by the server, as a [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict) instance mapping capability names to (possibly empty) lists of values. On legacy servers which don’t understand the `CAPABILITIES` command, an empty dictionary is returned instead.132133```python134>>> s = NNTP('news.gmane.org')135>>> 'POST' in s.getcapabilities()136True137```138139Новое в версии 3.2.140141#### `NNTP.login(user=None, password=None, usenetrc=True)`142143Отправляет команды `AUTHINFO` с именем пользователя и паролем. Если *user* и *password* равны None, а *usenetrc* равно True, по возможности будут использованы учётные данные из `~/.netrc`.144145Если намеренно не отложено, вход обычно выполняется во время инициализации объекта [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP), и отдельный вызов этой функции не требуется. Чтобы отложить аутентификацию, не указывайте *user* или *password* при создании объекта и установите *usenetrc* в False.146147Новое в версии 3.2.148149#### `NNTP.starttls(ssl_context=None)`150151Отправляет команду `STARTTLS`. Аргумент *ssl\_context* необязателен и должен быть объектом [`ssl.SSLContext`](https://python-all.ru/3.2/library/ssl.html#ssl.SSLContext). Это включит шифрование в NNTP-соединении.152153Обратите внимание, что это нельзя делать после передачи аутентификационных данных; аутентификация по умолчанию выполняется, если это возможно, во время инициализации объекта [`NNTP`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP). См. [`NNTP.login()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.login) для получения информации о том, как подавить это поведение.154155Новое в версии 3.2.156157#### `NNTP.newgroups(date, *, file=None)`158159Отправляет команду `NEWGROUPS`. Аргумент *date* должен быть объектом [`datetime.date`](https://python-all.ru/3.2/library/datetime.html#datetime.date) или [`datetime.datetime`](https://python-all.ru/3.2/library/datetime.html#datetime.datetime). Возвращает пару `(response, groups)`, где *groups* – это список, представляющий группы, появившиеся после указанной даты *date*. Однако если указан *file*, то *groups* будет пустым.160161```python162>>> from datetime import date, timedelta163>>> resp, groups = s.newgroups(date.today() - timedelta(days=3))164>>> len(groups)16585166>>> groups[0]167GroupInfo(group='gmane.network.tor.devel', last='4', first='1', flag='m')168```169170#### `NNTP.newnews(group, date, *, file=None)`171172Отправляет команду `NEWNEWS`. Здесь *group* – это имя группы или `'*'`, а *date* имеет то же значение, что и для [`newgroups()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.newgroups). Возвращает пару `(response, articles)`, где *articles* – это список идентификаторов сообщений.173174Эта команда часто отключается администраторами NNTP-серверов.175176#### `NNTP.list(group_pattern=None, *, file=None)`177178Отправляет команду `LIST` или `LIST ACTIVE`. Возвращает пару `(response, list)`, где *list* – это список кортежей, представляющих все группы, доступные на этом сервере NNTP, при необходимости соответствующие строке шаблона *group\_pattern*. Каждый кортеж имеет вид `(group, last, first, flag)`, где *group* – имя группы, *last* и *first* – номера последнего и первого сообщений, а *flag* обычно принимает одно из следующих значений:179180- `y`: разрешены локальные публикации и сообщения от других серверов.181- `m`: группа модерируется, и все публикации должны быть одобрены.182- `n`: локальные публикации запрещены, разрешены только сообщения от других серверов.183- `j`: сообщения от других серверов вместо этого помещаются в группу junk.184- `x`: локальные публикации запрещены, а сообщения от других серверов игнорируются.185- `=foo.bar`: сообщения вместо этого помещаются в группу `foo.bar`.186187Если *flag* имеет другое значение, статус группы новостей следует считать неизвестным.188189Эта команда может возвращать очень большие результаты, особенно если *group\_pattern* не указан. Результаты лучше кэшировать в автономном режиме, если только нет реальной необходимости их обновлять.190191Изменено в версии 3.2: Был добавлен параметр *group\_pattern*.192193#### `NNTP.descriptions(grouppattern)`194195Отправляет команду `LIST NEWSGROUPS`, где *grouppattern* – это строка wildmat, как указано в [**RFC 3977**](https://python-all.ru/3.2/library/nntplib.html) (она по сути аналогична строкам шаблонов DOS или UNIX). Возвращает пару `(response, descriptions)`, где *descriptions* – это словарь, сопоставляющий имена групп с текстовыми описаниями.196197```python198>>> resp, descs = s.descriptions('gmane.comp.python.*')199>>> len(descs)200295201>>> descs.popitem()202('gmane.comp.python.bio.general', 'BioPython discussion list (Moderated)')203```204205#### `NNTP.description(group)`206207Получает описание для одной группы *group*. Если совпадает несколько групп (если ‘group’ – это строка шаблона wildmat), возвращается первое совпадение. Если ни одна группа не совпадает, возвращается пустая строка.208209Этот метод опускает код ответа сервера. Если код ответа нужен, используйте [`descriptions()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.descriptions).210211#### `NNTP.group(name)`212213Отправляет команду `GROUP`, где *name* – имя группы. Группа выбирается в качестве текущей, если она существует. Возвращает кортеж `(response, count, first, last, name)`, где *count* – (приблизительное) количество сообщений в группе, *first* – номер первого сообщения, *last* – номер последнего сообщения, а *name* – имя группы.214215#### `NNTP.over(message_spec, *, file=None)`216217Отправляет команду `OVER` или команду `XOVER` на устаревших серверах. *message\_spec* может быть либо строкой, представляющей идентификатор сообщения, либо кортежем `(first, last)` чисел, указывающим диапазон статей в текущей группе, либо кортежем `(first, None)`, указывающим диапазон статей от *first* до последней статьи в текущей группе, или [`None`](https://python-all.ru/3.2/library/constants.html#None) для выбора текущей статьи в текущей группе.218219Возвращает пару `(response, overviews)`. *overviews* – это список кортежей `(article_number, overview)`, по одному на каждое сообщение, выбранное *message\_spec*. Каждый *overview* – это словарь с одинаковым количеством элементов, но это количество зависит от сервера. Эти элементы могут быть либо заголовками сообщения (тогда ключ – имя заголовка в нижнем регистре), либо элементами метаданных (тогда ключ – имя метаданных с префиксом `":"`). Следующие элементы гарантированно присутствуют согласно спецификации NNTP:220221- заголовки `subject`, `from`, `date`, `message-id` и `references`222- метаданные `:bytes`: количество байтов во всём необработанном сообщении (включая заголовки и тело)223- метаданные `:lines`: количество строк в теле сообщения224225Значение каждого элемента – строка или [`None`](https://python-all.ru/3.2/library/constants.html#None), если он отсутствует.226227Рекомендуется использовать функцию [`decode_header()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.decode_header) для значений заголовков, которые могут содержать не-ASCII символы:228229```python230>>> _, _, first, last, _ = s.group('gmane.comp.python.devel')231>>> resp, overviews = s.over((last, last))232>>> art_num, over = overviews[0]233>>> art_num234117216235>>> list(over.keys())236['xref', 'from', ':lines', ':bytes', 'references', 'date', 'message-id', 'subject']237>>> over['from']238'=?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?= <martin@v.loewis.de>'239>>> nntplib.decode_header(over['from'])240'"Martin v. Löwis" <martin@v.loewis.de>'241```242243Новое в версии 3.2.244245#### `NNTP.help(*, file=None)`246247Отправляет команду `HELP`. Возвращает пару `(response, list)`, где *list* – это список строк справки.248249#### `NNTP.stat(message_spec=None)`250251Отправляет команду `STAT`, где *message\_spec* – это либо идентификатор сообщения (заключённый в `'<'` и `'>'`), либо номер сообщения в текущей группе. Если *message\_spec* опущен или равен [`None`](https://python-all.ru/3.2/library/constants.html#None), рассматривается текущее сообщение в текущей группе. Возвращает тройку `(response, number, id)`, где *number* – номер сообщения, а *id* – идентификатор сообщения.252253```python254>>> _, _, first, last, _ = s.group('gmane.comp.python.devel')255>>> resp, number, message_id = s.stat(first)256>>> number, message_id257(9099, '<20030112190404.GE29873@epoch.metaslash.com>')258```259260#### `NNTP.next()`261262Отправляет команду `NEXT`. Возвращаемое значение – как у [`stat()`](https://python-all.ru/3.2/library/stat.html#module-stat).263264#### `NNTP.last()`265266Отправляет команду `LAST`. Возвращаемое значение – как у [`stat()`](https://python-all.ru/3.2/library/stat.html#module-stat).267268#### `NNTP.article(message_spec=None, *, file=None)`269270Отправляет команду `ARTICLE`, где *message\_spec* имеет то же значение, что и для [`stat()`](https://python-all.ru/3.2/library/stat.html#module-stat). Возвращает кортеж `(response, info)`, где *info* – это [`namedtuple`](https://python-all.ru/3.2/library/collections.html#collections.namedtuple) с тремя атрибутами *number*, *message\_id* и *lines* (в указанном порядке). *number* – номер статьи в группе (или 0, если информация недоступна), *message\_id* – идентификатор сообщения в виде строки, а *lines* – список строк (без завершающих символов новой строки), составляющих исходное сообщение, включая заголовки и тело.271272```python273>>> resp, info = s.article('<20030112190404.GE29873@epoch.metaslash.com>')274>>> info.number2750276>>> info.message_id277'<20030112190404.GE29873@epoch.metaslash.com>'278>>> len(info.lines)27965280>>> info.lines[0]281b'Path: main.gmane.org!not-for-mail'282>>> info.lines[1]283b'From: Neal Norwitz <neal@metaslash.com>'284>>> info.lines[-3:]285[b'There is a patch for 2.3 as well as 2.2.', b'', b'Neal']286```287288#### `NNTP.head(message_spec=None, *, file=None)`289290То же, что и [`article()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.article), но отправляет команду `HEAD`. Возвращаемые *lines* (или записанные в *file*) будут содержать только заголовки сообщения, но не тело.291292#### `NNTP.body(message_spec=None, *, file=None)`293294То же, что и [`article()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.article), но отправляет команду `BODY`. Возвращаемые *lines* (или записанные в *file*) будут содержать только тело сообщения, а не заголовки.295296#### `NNTP.post(data)`297298Отправляет статью с помощью команды `POST`. Аргумент *data* может быть либо [*файловым объектом*](https://python-all.ru/3.2/glossary.html#term-file-object), открытым для двоичного чтения, либо любым итерируемым объектом из байтовых строк (представляющих исходные строки публикуемой статьи). Он должен представлять правильно оформленную новостную статью, включая необходимые заголовки. Метод [`post()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.post) автоматически экранирует строки, начинающиеся с `.`, и добавляет завершающую строку.299300В случае успеха возвращается ответ сервера. Если сервер отказывается принимать публикацию, возбуждается [`NNTPReplyError`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTPReplyError).301302#### `NNTP.ihave(message_id, data)`303304Отправляет команду `IHAVE`. *message\_id* – это идентификатор сообщения для отправки серверу (заключённый в `'<'` и `'>'`). Параметр *data* и возвращаемое значение такие же, как для [`post()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.post).305306#### `NNTP.date()`307308Возвращает пару `(response, date)`. *date* – это объект [`datetime`](https://python-all.ru/3.2/library/datetime.html#datetime.datetime), содержащий текущие дату и время сервера.309310#### `NNTP.slave()`311312Отправляет команду `SLAVE`. Возвращает *response* сервера.313314#### `NNTP.set_debuglevel(level)`315316Устанавливает уровень отладки экземпляра. Он управляет объёмом выводимых отладочных сообщений. Значение по умолчанию, `0`, не выводит отладочные сообщения. Значение `1` выдаёт умеренное количество отладочной информации, обычно одну строку на запрос или ответ. Значение `2` или больше выводит максимальный объём отладочной информации, регистрируя каждую отправленную и полученную строку соединения (включая текст сообщения).317318Ниже перечислены необязательные расширения NNTP, определённые в [**RFC 2980**](https://python-all.ru/3.2/library/nntplib.html). Некоторые из них заменены более новыми командами в [**RFC 3977**](https://python-all.ru/3.2/library/nntplib.html).319320#### `NNTP.xhdr(hdr, str, *, file=None)`321322Отправляет команду `XHDR`. Аргумент *hdr* – это ключевое слово заголовка, например, `'subject'`. Аргумент *str* должен иметь вид `'first-last'`, где *first* и *last* – первый и последний номера статей для поиска. Возвращает пару `(response, list)`, где *list* – это список пар `(id, text)`; *id* – номер статьи (в виде строки), а *text* – текст запрошенного заголовка для этой статьи. Если указан параметр *file*, выходные данные команды `XHDR` сохраняются в файл. Если *file* – строка, метод откроет файл с таким именем, запишет в него данные и закроет его. Если *file* – это [*файловый объект*](https://python-all.ru/3.2/glossary.html#term-file-object), он будет вызывать `write()` для него, чтобы сохранить строки выходных данных команды. Если *file* указан, то возвращаемый *list* будет пустым списком.323324#### `NNTP.xover(start, end, *, file=None)`325326Отправляет команду `XOVER`. *start* и *end* – это номера статей, определяющие диапазон статей для выбора. Возвращаемое значение такое же, как для [`over()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.over). Рекомендуется использовать [`over()`](https://python-all.ru/3.2/library/nntplib.html#nntplib.NNTP.over), так как он автоматически применит более новую команду `OVER`, если она доступна.327328#### `NNTP.xpath(id)`329330Возвращает пару `(resp, path)`, где *path* – это путь к каталогу статьи с идентификатором сообщения *id*. В большинстве случаев это расширение не включено администраторами серверов NNTP.331332## 20.14.2. Вспомогательные функции333334Модуль также определяет следующую вспомогательную функцию:335336#### `nntplib.decode_header(header_str)`337338Декодирует значение заголовка, снимая экранирование любых экранированных не-ASCII символов. *header\_str* должен быть объектом [`str`](https://python-all.ru/3.2/library/functions.html#str). Возвращается нераскодированное значение. Эту функцию рекомендуется использовать для отображения некоторых заголовков в удобочитаемой форме:339340```python341>>> decode_header("Some subject")342'Some subject'343>>> decode_header("=?ISO-8859-15?Q?D=E9buter_en_Python?=")344'Débuter en Python'345>>> decode_header("Re: =?UTF-8?B?cHJvYmzDqG1lIGRlIG1hdHJpY2U=?=")346'Re: problème de matrice'347```348