КАКОЙ МОДУЛЬ СТАНДАРТНОЙ БИБЛИОТЕКИ PYTHON ПОЗВОЛЯЕТ РАБОТАТЬ С WWW НА БОЛЕЕ НИЗКОМ УРОВНЕ
Стандартная библиотека Python содержит модуль socket , который предоставляет возможность работать с сетью на низком уровне. Этот модуль позволяет осуществлять прямой доступ к сокетам, используемым для передачи данных по сети.
Чтобы выполнить HTTP-запрос, необходимо установить соединение с сервером, сформировать HTTP-запрос и отправить его. В следующем примере показано, как выполнить GET-запрос к серверу Google:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((‘www.google.com’, 80))
s.sendall(b’GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n’)
data = s.recv(1024)
s.close()
print(repr(data))
В этом примере мы создаем сокет и устанавливаем соединение с сервером Google на порту 80. Затем мы отправляем GET-запрос, запросив содержимое корневой страницы. Наконец, мы получаем ответ от сервера и закрываем соединение с сокетом.
Хотя модуль socket предоставляет возможность осуществлять прямой доступ к сокетам, использование этого модуля может быть достаточно сложным для большинства задач, связанных с работой в сети. В таких случаях рекомендуется использовать более высокоуровневые библиотеки, такие как http.client или urllib.request .
Python ТОП 10 крутейших библиотек!
Python requests http, https запросы, requests методы get и post, подключаемся к api через python
Работа с сетью в Python: Socket и HTTP. Python Advanced. Урок 1
Основы NumPy Python — Массивы, Матрицы И Операции Над Ними
Работа с HTTP в Python. Библиотека requests. Модули в Python
Python с нуля. Урок 8 — Модули
Язык программирования Python — что на нем пишут, сколько за него платят
5 Лучших Библиотек Для Программирования На Python — Библиотеки Которые Должен Знать Каждый
#5. Математические функции и работа с модулем math — Python для начинающих

BLGPG-75F9CEFCBF26-23-11-23-14
Новые материалы:
- Deque методы python
- Python тип данных bytes
- Игры на pyqt
- Maximum recursion depth exceeded while calling a python object что значит
- Асинхронные фреймворки python
- Обращение фрагмента python
- Мешок слов python
- Python виртуальная машина
- Перевод кода из python в c
- Даны катеты прямоугольного треугольника найти его периметр python
Стандартная библиотека¶
Стандартная библиотека Python содержит огромное количество полезных модулей и является частью стандартного комплекта поставки Python. Ознакомиться со стандартной библиотекой Python очень важно, так как множество задач можно решить очень быстро, если вы знакомы с возможностями этих библиотек.
Рассмотрим некоторые наиболее часто используемые модули этой библиотеки. Детальное описание всех модулей стандартной библиотеки Python можно найти в разделе «Library Reference» документации, входящей в комплект поставки Python.
Давайте изучим несколько полезных модулей.
Если темы в настоящей главе покажутся вам слишком сложными, вы можете её пропустить. Однако я настоятельно рекомендую вернуться к этой главе, когда вы будете чувствовать себя более уверенно с Python.
Модуль sys¶
Модуль sys содержит функциональность, характерную для системы. Так мы видели, что список sys.argv содержит аргументы командной строки.
Предположим, нам нужно узнать версию используемой команды Python с тем, чтобы, к примеру, убедиться в том, что мы используем как минимум версию 3. Модуль sys предоставляет такую возможность.
>>> import sys >>> sys.version_info (3, 0, 0, 'beta', 2) >>> sys.version_info[0] >= 3 True
Как это работает:
Модуль sys содержит кортеж version_info , который хранит информацию о версии. Первый элемент этого кортежа обозначает старшую версию. Мы можем использовать его, например, для того, чтобы убедиться, что программа будет выполняться только в Python 3.0:
Сохраните как versioncheck.py :
import sys, warnings if sys.version_info[0] 3: warnings.warn("Для выполнения этой программы необходима как минимум \ версия Python 3.0", RuntimeWarning) else: print('Нормальное продолжение')
Вывод:
$ python2.7 versioncheck.py versioncheck.py:6: Для выполнения этой программы необходима как минимум версия Python 3.0 RuntimeWarning) $ python3 versioncheck.py Нормальное продолжение
Как это работает:
Мы используем один из модулей стандартной библиотеки, который называется warnings и служит для отображения предупреждений пользователю. Если версия Python менее 3, мы показываем соответствующее предупреждение.
Модуль logging¶
Представьте ситуацию, когда необходимо сохранить некоторые отладочные или другие важные сообщения где-нибудь, чтобы иметь возможность позже проверить, отработала ли программа, как ожидалось. Как мы «сохраним где-нибудь» эти сообщения? Сделать это можно при помощи модуля logging .
Сохраните как use_logging.py :
import os, platform, logging if platform.platform().startswith('Windows'): logging_file = os.path.join(os.getenv('HOMEDRIVE'), os.getenv('HOMEPATH'), 'test.log') else: logging_file = os.path.join(os.getenv('HOME'), 'test.log') print("Сохраняем лог в", logging_file) logging.basicConfig( level=logging.DEBUG, format='%(asctime)s : %(levelname)s : %(message)s', filename = logging_file, filemode = 'w', ) logging.debug("Начало программы") logging.info("Какие-то действия") logging.warning("Программа умирает")
Вывод:
$ python3 use_logging.py Сохраняем лог в C:\Users\swaroop\test.log
Если открыть файл test.log , он будет выглядеть примерно так:
2012-10-26 16:52:41,457 : DEBUG : Начало программы 2012-10-26 16:52:41,474 : INFO : Какие-то действия 2012-10-26 16:52:41,475 : WARNING : Программа умирает
Как это работает:
Мы использовали три модуля из стандартной библиотеки: модуль os для взаимодействия с операционной системой, модуль platform для получения информации о платформе (т.е. операционной системе) и модуль logging для сохранения лога 1 .
Прежде всего, при помощи строки, возвращаемой функцией platform.platform() мы проверяем, какая операционная система используется (для более подробной информации см. import platform; help(platform) ). Если это Windows, то мы определяем диск, содержащий домашний каталог, путь к домашнему каталогу на нём и имя файла, в котором хотим сохранить информацию. Сложив все эти три части, мы получаем полный путь к файлу. Для других платформ нам нужно знать только путь к домашнему каталогу пользователя, и мы получим полный путь к файлу.
При помощи функции os.path.join() мы объединяем три части пути к файлу вместе. Мы используем эту функцию вместо простого объединения строк для того, чтобы гарантировать, что полный путь к файлу записан в формате, ожидаемом операционной системой.
Далее мы конфигурируем модуль logging таким образом, чтобы он записывал все сообщения в определённом формате в указанный файл.
Наконец, мы можем выводить сообщения, предназначенные для отладки, информирования, предупреждения и даже критические сообщения. После выполнения программы можно просмотреть этот файл и узнать, что происходило в программе, хотя пользователю, запустившему программу, ничего не было показано.
Модули urllib и json¶
#!/usr/bin/python # Filename: yahoo_search.py import sys if sys.version_info[0] != 3: sys.exit('This program needs Python 3.0') import json import urllib, urllib.parse, urllib.request, urllib.response # Get your own APP ID at http://developer.yahoo.com/wsregapp/ YAHOO_APP_ID = 'jl22psvV34HELWhdfUJbfDQzlJ2B57KFS_qs4I8D0Wz5U5_yCI1Awv8.lBSfPhwr' SEARCH_BASE = 'http://search.yahooapis.com/WebSearchService/V1/webSearch' class YahooSearchError(Exception): pass # Taken from http://developer.yahoo.com/python/python-json.html def search(query, results=20, start=1, **kwargs): kwargs.update( 'appid': YAHOO_APP_ID, 'query': query, 'results': results, 'start': start, 'output': 'json' >) url = SEARCH_BASE + '?' + urllib.parse.urlencode(kwargs) result = json.load(urllib.request.urlopen(url)) if 'Error' in result: raise YahooSearchError(result['Error']) return result['ResultSet'] query = input('What do you want to search for? ') for result in search(query)['Result']: print(" : ".format(result['Title'], result['Url']))
Резюме¶
Мы изучили лишь некоторые возможности некоторых модулей стандартной библиотеки Python. Я настоятельно рекомендую просмотреть документацию по стандартной библиотеке Python, чтобы увидеть все доступные модули.
Далее мы обратимся к некоторым аспектам, которые сделают вашу экскурсию по Python более «завершённой».
- log — англ. «журнал», «вести журнал» (прим.перев.) ↩
Какой модуль стандартной библиотеки python позволяет работать с www на более низком уровне
Содержание справочника по модулям, поставляемым с интерпретатором Python3.
Представленным здесь модулям, какая либо дополнительная установка не требуется.
Модуль ipaddress в Python.
Модуль ipaddress предоставляет возможности для создания, управления и работы с адресами и сетями IPv4 и IPv6. Модуль упрощают выполнение различных задач, связанных с IP-адресами, включая проверку того, находятся ли два хоста в одной подсети, представляет ли строка действительный IP-адрес или опреде
Модуль http.server в Python.
Модуль http.server определяет классы для реализации HTTP-серверов (веб-серверов). Модуль http.server не рекомендуется для использования в продакшне, так как он выполняет только базовые проверки безопасности.
Модуль zipimport в Python, импорт ZIP-архива.
Модуль zipimport добавляет возможность импорта модулей Python (*.py, *.pyc) и пакетов из архивов формата ZIP. Обычно явно не требуется использовать модуль zipimport, он автоматически используется встроенным механизмом импорта для элементов sys.path, которые являются путями к архивам ZIP.
Модуль bisect в Python, вставка в отсортированный список.
Модуль bisect обеспечивает поддержку вставки значений в отсортированный список, без необходимости сортировать этот список после каждой вставки. Для длинных списков элементов с дорогостоящими операциями сравнения это может быть улучшением по сравнению с более распространенным подходом.
Графический модуль turtle в Python.
Графика с черепахой — популярный способ познакомить детей с программированием. Модуль turtle предоставляет графические примитивы черепахи как объектно-ориентированным, так и процедурно-ориентированным способами. Так как turtle для базовой графики использует tkinter, то необходима версия Python, уст
Модуль tomllib в Python, разбор файлов TOML
Модуль tomllib предоставляет интерфейс для разбора файлов с синтаксисом TOML. Этот модуль не поддерживает запись файлов TOML. Он полностью совместим с TOML v1.0.0. Модуль tomllib — это версия стороннего модуля tomli который (согласно PEP 680) добавлен в стандартную библиотеку в Python 3.11.
Модуль colorsys в Python, преобразования цвета.
Модуль colorsys определяет двунаправленное преобразование цветовых значений между цветовыми системами, выраженными в цветовом пространстве RGB (красный, зеленый, синий), используемом в компьютерных мониторах, и в трех других системах координат: YIQ, HLS (оттенок, яркость, насыщенность) и HSV (оттен
Модуль mmap в Python, ускорение операций ввода-вывода.
Модуль mmap обеспечивает ввод и вывод файла с отображением памяти (I/O). Это позволяет использовать функциональные возможности операционной системы более низкого уровня для чтения файлов, как если бы они были одной большой строкой или массивом. Это может значительно улучшить производительность кода
Курсы/Язык программирования Python/Лекция 9: Сетевые приложения на Python
Аннотация: В этой лекции рассматривается реализация на Python простейшего клиент-серверного приложения, дается представление о типичном для сети Internet приложении. Стандартная библиотека Python имеет несколько модулей для работы с различными протоколами. Этими модулями охватываются как низкоуровневые протоколы (TCP/IP, UDP/IP), так и высокоуровневые (HTTP, FTP, SMTP, POP3, IMAP, NNTP, . ). Здесь будет рассмотрена работа с сокетами (модуль socket) и три модуля высокоуровневых протоколов (urllib2, poplib, smtplib). При этом предполагается, что имеется понимание принципов работы IP-сети и некоторых ее сервисов, а также представление о системе WWW.
Работа с сокетами
Применяемая в IP-сетях архитектура клиент-сервер использует IP-пакеты для коммуникации между клиентом и сервером. Клиент отправляет запрос серверу, на который тот отвечает. В случае с TCP/IP между клиентом и сервером устанавливается соединение (обычно с двусторонней передачей данных), а в случае с UDP/IP — клиент и сервер обмениваются пакетами (дейтаграммамми) с негарантированной доставкой.
Каждый сетевой интерфейс IP-сети имеет уникальный в этой сети адрес (IP-адрес). Упрощенно можно считать, что каждый компьютер в сети Интернет имеет собственный IP-адрес. При этом в рамках одного сетевого интерфейса может быть несколько сетевых портов. Для установления сетевого соединения приложение клиента должно выбрать свободный порт и установить соединение с серверным приложением, которое слушает (listen) порт с определенным номером на удаленном сетевом интерфейсе. Пара IP-адрес и порт характеризуют сокет (гнездо) — начальную (конечную) точку сетевой коммуникации. Для создания соединения TCP/IP необходимо два сокета: один на локальной машине, а другой — на удаленной. Таким образом, каждое сетевое соединение имеет IP-адрес и порт на локальной машине, а также IP-адрес и порт на удаленной машине.
Модуль socket обеспечивает возможность работать с сокетами из Python. Сокеты используют транспортный уровень согласно семиуровневой модели OSI (Open Systems Interconnection, взаимодействие открытых систем), то есть относятся к более низкому уровню, чем большинство описываемых в этом разделе протоколов.
Уровни модели OSI:
Поток битов, передаваемых по физической линии. Определяет параметры физической линии.
Канальный (Ethernet, PPP, ATM и т.п.)
Кодирует и декодирует данные в виде потока битов, справляясь с ошибками, возникающими на физическом уровне в пределах физически единой сети.
Сетевой (IP)
Маршрутизирует информационные пакеты от узла к узлу.
Транспортный (TCP, UDP и т.п.)
Обеспечивает прозрачную передачу данных между двумя точками соединения.
Управляет сеансом соединения между участниками сети. Начинает, координирует и завершает соединения.
Представления
Обеспечивает независимость данных от формы их представления путем преобразования форматов. На этом уровне может выполняться прозрачное (с точки зрения вышележащего уровня) шифрование и дешифрование данных.
Приложений (HTTP, FTP, SMTP, NNTP, POP3, IMAP и т.д.)
Поддерживает конкретные сетевые приложения. Протокол зависит от типа сервиса.
Каждый сокет относится к одному из коммуникационных доменов. Модуль socket поддерживает домены UNIX и Internet. Каждый домен подразумевает свое семейство протоколов и адресацию. Данное изложение будет затрагивать только домен Internet, а именно протоколы TCP/IP и UDP/IP, поэтому для указания коммуникационного домена при создании сокета будет указываться константа socket.AF_INET .
В качестве примера следует рассмотреть простейшую клиент-серверную пару. Сервер будет принимать строку и отвечать клиенту. Сетевое устройство иногда называют хостом (host), поэтому будет употребляться этот термин по отношению к компьютеру, на котором работает сетевое приложение.
В примере использованы русские буквы: необходимо указывать кодировку.
Прежде всего, нужно запустить сервер. Сервер открывает сокет на локальной машине на порту 33333, и адресе 127.0.0.1. После этого он слушает ( listen() ) порт. Когда на порту появляются данные, принимается ( accept() ) входящее соединение. Метод accept() возвращает пару — Socket-объект и адрес удаленного компьютера, устанавливающего соединение (пара — IP-адрес, порт на удаленной машине). После этого можно применять методы recv() и send() для общения с клиентом. В recv() задается число байтов в очередной порции. От клиента может прийти и меньшее количество данных.
Код программы-клиента достаточно очевиден. Метод connect() устанавливает соединение с удаленным хостом (в приведенном примере он расположен на той же машине). Данные передаются методом send() и принимаются методом recv() — аналогично тому, что происходит на сервере.
Модуль socket имеет несколько вспомогательных функций. В частности, функции для работы с системой доменных имен (DNS):
В новых версиях Python появилась такая функция как socket.getservbyname() . Она позволяет преобразовывать наименования Интернет-сервисов в общепринятые номера портов:
Модуль также содержит большое количество констант для указания протоколов, типов сокетов, коммуникационных доменов и т.п. Другие функции модуля socket можно при необходимости изучить по документации.
Модуль smtplib
Сообщения электронной почты в Интернете передаются от клиента к серверу и между серверами в основном по протоколу SMTP (Simple Mail Transfer Protocol, простой протокол передачи почты). Протокол SMTP и ESMTP (расширенный вариант SMTP) описаны в 821 и 1869. Для работы с SMTP в стандартной библиотеке модулей имеется модуль smtplib . Для того чтобы начать SMTP-соединение с сервером электронной почты, необходимо в начале создать объект для управления SMTP-сессией с помощью конструктора класса SMTP :
Параметры host и port задают адрес и порт SMTP-сервера, через который будет отправляться почта. По умолчанию, port=25 . Если host задан, конструктор сам установит соединение, иначе придется отдельно вызывать метод connect() . Экземпляры класса SMTP имеют методы для всех распространенных команд SMTP-протокола, но для отправки почты достаточно вызова конструктора и методов sendmail() и quit() :
Следует заметить, что toaddr в сообщении (в поле To ) и при отправке могут не совпадать. Дело в том, что получатель и отправитель в ходе SMTP-сессии передается командами SMTP-протокола. При запуске указанного выше примера на экране появится отладочная информация (ведь уровень отладки задан равным 1):
Из этой (несколько сокращенной) отладочной информации можно увидеть, что клиент отправляет (send) команды SMTP-серверу (EHLO, MAIL FROM, RCPT TO, DATA, QUIT), а тот выполняет команды и отвечает (reply), возвращая код возврата.
В ходе одной SMTP-сессии можно отправить сразу несколько писем подряд, если не вызывать quit() .
В принципе, команды SMTP можно подавать и отдельно: для этого у объекта-соединения есть методы ( helo() , ehlo() , expn() , help() , mail() , rcpt() , vrfy() , send() , noop() , data() ), соответствующие одноименным командам SMTP-протокола.
Можно задать и произвольную команду SMTP-серверу с помощью метода docmd() . В следующем примере показан простейший сценарий, который могут использовать те, кто время от времени принимает почту на свой сервер по протоколу SMTP от почтового сервера, на котором хранится очередь сообщений для некоторого домена:
Этот простенький сценарий предлагает серверу mx.abcde.ru попытаться связаться с основным почтовым сервером домена rnd.abcde.ru и переслать всю накопившуюся для него почту.
При работе с классом smtplib.SMTP могут возбуждаться различные исключения. Назначение некоторых из них приведено ниже:
Базовый класс для всех исключений модуля.
Сервер неожиданно прервал связь (или связь с сервером не была установлена).
Базовый класс для всех исключений, которые имеют код ответа SMTP-сервера.
Все получатели отвергнуты сервером.
Сервер ответил неизвестным кодом на данные сообщения.
Ошибка установления соединения.
Сервер не ответил правильно на команду HELO или отверг ее.
Модуль poplib
Еще один протокол — POP3 (Post Office Protocol, почтовый протокол) — служит для приема почты из почтового ящика на сервере (протокол определен в RFC 1725).
Для работы с почтовым сервером требуется установить с ним соединение и, подобно рассмотренному выше примеру, с помощью SMTP-команд получить требуемые сообщения. Объект-соединение POP3 можно установить посредством конструктора класса POP3 из модуля poplib :
Где host — адрес POP3-сервера, port — порт на сервере (по умолчанию 110), pop_obj — объект для управления сеансом работы с POP3-сервером.
Следующий пример демонстрирует основные методы для работы с POP3-соединением:
Разумеется, чтобы пример сработал корректно, необходимо внести реальные учетные данные.
При выполнении сценарий выведет на экран примерно следующее.
Эти и другие методы экземпляров класса POP3 описаны ниже:
| Метод | Команда POP3 | Описание |
|---|---|---|
| getwelcome() | Получает строку s с приветствием POP3-сервера | |
| user(name) | USER name | Посылает команду USER с указанием имени пользователя name . Возвращает строку с ответом сервера |
| pass_(pwd) | PASS pwd | Отправляет пароль пользователя в команде PASS. После этой команды и до выполнения команды QUIT почтовый ящик блокируется |
| apop(user, secret) | APOP user secret | Идентификация на сервере по APOP |
| rpop(user) | RPOP user | Идентификация по методу RPOP |
| stat() | STAT | Возвращает кортеж с информацией о почтовом ящике. В нем m — количество сообщений, l — размер почтового ящика в байтах |
| list([num]) | LIST [num] | Возвращает список сообщений в формате (resp, [‘num octets’, . ]) , если не указан num , и «+OK num octets» , если указан. Список lst состоит из строк в формате «num octets» . |
| retr(num) | RETR num | Загружает с сервера сообщение с номером num и возвращает кортеж с ответом сервера (resp, lst, octets) |
| dele(num) | DELE num | Удаляет сообщение с номером num |
| rset() | RSET | Отменяет пометки удаления сообщений |
| noop() | NOOP | Ничего не делает (поддерживает соединение) |
| quit() | QUIT | Отключение от сервера. Сервер выполняет все необходимые изменения (удаляет сообщения) и снимает блокировку почтового ящика |
| top(num, lines) | TOP num lines | Команда аналогична RETR, но загружает только заголовок и lines строк тела сообщения. Возвращает кортеж (resp, lst, octets) |
| uidl([num]) | UIDL [num] | Сокращение от «unique-id listing» (список уникальных идентификаторов сообщений). Формат результата: (resp, lst, octets) , если num не указан, и «+OK num uniqid» , если указан. Список lst состоит из строк вида «+OK num uniqid» |
В этой таблице num обозначает номер сообщения (он не меняется на протяжении всей сессии), resp — ответ сервера, возвращается для любой команды, начинается с «+OK » для успешных операций (при неудаче возбуждается исключение poplib.proto_error ). Параметр octets обозначает количество байт в принятых данных. uniqid — идентификатор сообщения, генерируемый сервером.
Работа с POP3-сервером состоит из трех фаз: идентификации, транзакций и обновления. На этапе идентификации сразу после создания POP3-объекта разрешены только команды USER, PASS (иногда APOP и RPOP). После идентификации сервер получает информацию о пользователе и наступает этап транзакций. Здесь уместны остальные команды. Этап обновления вызывается командой QUIT, после которой POP3-сервер обновляет почтовый ящик пользователя в соответствии с поданными командами, а именно — удаляет помеченные для удаления сообщения.
Модули для клиента WWW
Стандартные средства языка Python позволяют получать из программы доступ к объектам WWW как в простых случаях, так и при сложных обстоятельствах, в частности при необходимости передавать данные формы, идентификации, доступа через прокси и т.п.
Стоит отметить, что при работе с WWW используется в основном протокол HTTP, однако WWW охватывает не только HTTP, но и многие другие схемы (FTP, gopher, HTTPS и т.п.). Используемая схема обычно указана в самом начале URL.
Функции для загрузки сетевых объектов
Простой случай получения WWW-объекта по известному URL показан в следующем примере:
Функция urllib.urlopen() создает файлоподобный объект, который читает методом read() . Другие методы этого объекта: readline() , readlines() , fileno() , close() работают как и у обычного файла, а также есть метод info() , который возвращает соответствующий полученному с сервера Message-объект. Этот объект можно использовать для получения дополнительной информации:
С помощью функции urllib.urlopen() можно делать и более сложные вещи, например, передавать web-серверу данные формы. Как известно, данные заполненной web-формы могут быть переданы на web-сервер с использованием метода GET или метода POST. Метод GET связан с кодированием всех передаваемых параметров после знака «?» в URL, а при методе POST данные передаются в теле HTTP-запроса. Оба варианта передачи представлены ниже:
В некоторых случаях данные имеют повторяющиеся имена. В этом случае в качестве параметра urllib.urlencode() можно использовать вместо словаря последовательность пар имя-значение:
Модуль urllib позволяет загружать web-объекты через прокси-сервер. Если ничего не указывать, будет использоваться прокси-сервер, который был задан принятым в конкретной ОС способом. В Unix прокси-серверы задаются в переменных окружения http_proxy , ftp_proxy и т.п., в Windows прокси-серверы записаны в реестре, а в Mac OS они берутся из конфигурации Internet. Задать прокси-сервер можно и как именованный параметр proxies к urllib.urlopen() :
Функция urlretrieve() позволяет записать заданный URL сетевой объект в файл. Она имеет следующие параметры:
Здесь url — URL сетевого объекта, filename — имя локального файла для помещения объекта, reporthook — функция, которая будет вызываться для сообщения о состоянии загрузки, data — данные для метода POST (если он используется). Функция возвращает кортеж (filepath, headers) , где filepath — имя локального файла, в который закачан объект, headers — результат метода info() для объекта, возвращенного urlopen() .
Для обеспечения интерактивности функция urllib.urlretrieve() вызывает время от времени функцию, заданную в reporthook() . Этой функции передаются три аргумента: количество принятых блоков, размер блока и общий размер принимаемого объекта в байтах (если он неизвестен, этот параметр равен -1).
В следующем примере программа принимает большой файл и, чтобы пользователь не скучал, пишет процент от выполненной загрузки и предполагаемое оставшееся время:
Эта программа выведет примерно следующее (процент от полного объема закачки, прошедшие секунды, предполагаемое оставшееся время, закачанные байты, полное количество байтов):
Функции для анализа URL
Согласно документу 2396 URL должен строиться по следующему шаблону:
Адресная схема. Например: http, ftp, gopher.
Местонахождение в сети.
Одна из функций уже использовалась для формирования URL — urllib.urlencode() . Кроме нее в модуле urllib имеются и другие функции:
Функция экранирует символы в URL, чтобы их можно было отправлять на web-сервер. Она предназначена для экранирования пути к ресурсу, поэтому оставляет ‘/’ как есть. Например:
Функция экранирует некоторые символы в URL (в строке запроса), чтобы их можно было отправлять на web-сервер. Аналогична quote() , но заменяет пробелы на плюсы.
Преобразование, обратное quote_plus() . Пример:
Преобразование, обратное quote_plus() . Пример:
Для анализа URL можно использовать функции из модуля urlparse :
Разбирает URL в 6 компонентов (сохраняя экранирование символов): scheme://netloc/path;params?query#frag
Разбирает URL в 6 компонентов (сохраняя экранирование символов): scheme://netloc/path?query#frag
Собирает URL из 6 компонентов.
Собирает URL из 5 компонентов.
Еще одна функция того же модуля urlparse позволяет корректно соединить две части URL — базовую и относительную:
Возможности urllib2
Функциональности модулей urllib и urlparse хватает для большинства задач, которые решают сценарии на Python как web-клиенты. Тем не менее, иногда требуется больше. На этот случай можно использовать модуль для работы с протоколом HTTP — httplib — и создать собственный класс для HTTP-запросов (в лекциях модуль httplib не рассматривается). Однако вполне вероятно, что нужная функциональность уже имеется в модуле urllib2 .
Одна из полезных возможностей этих модулей — доступ к web-объектам, требующий авторизации. Ниже будет рассмотрен пример, который не только обеспечит доступ с авторизацией, но и обозначит основную идею модуля urllib2: использование обработчиков (handlers), каждый из которых решает узкую специфическую задачу.
Следующий пример показывает, как создать собственный открыватель URL с помощью модуля urllib2 (этот пример взят из документации по Python):
В этом примере получен доступ к странице, которую охраняет mod_python (см. предыдущую лекцию). Первый аргумент при вызове метода add_password() задает область действия (realm) идентификационных данных (он задан директивой AuthName «My page» в конфигурации web-сервера). Остальные параметры достаточно понятны: имя хоста, на который нужно получить доступ, имя пользователя и его пароль. Разумеется, для корректной работы примера нужно, чтобы на локальном web-сервере был каталог, требующий авторизации.
В данном примере явным образом затронуты всего три обработчика: HTTPBasicAuthHandler , ProxyHandler и CacheFTPHandler . В модуле urllib2 их более десятка, назначение каждого можно узнать из документации к используемой версии Python. Есть и специальный класс для управления открывателями: OpenerDirector . Именно его экземпляр создала функция urllib2.build_opener() .
Модуль urllib2 имеет и специальный класс для воплощения запроса на открытие URL. Называется этот класс urllib2.Request . Его экземпляр содержит состояние запроса. Следующий пример показывает, как получить доступ к каталогу с авторизацией, используя добавление заголовка в HTTP-запрос:
Как видно из этого примера, ничего загадочного в авторизации нет: web-клиент вносит (закодированные base64) идентификационные данные в поле Authorization HTTP-запроса.
Приведенные два примера почти эквивалентны, только во втором примере прокси-сервер не назначен явно.
XML-RPC сервер
До сих пор высокоуровневые протоколы рассматривались с точки зрения клиента. Не менее просто создавать на Python и их серверные части. Для иллюстрации того, как разработать программу на Python, реализующую сервер, был выбран протокол XML-RPC. Несмотря на свое название, конечному пользователю необязательно знать XML (об этом языке разметки говорилось на одной из предыдущих лекций), так как он скрыт от него. Сокращение RPC (Remote Procedure Call, вызов удаленной процедуры) объясняет суть дела: с помощью XML-RPC можно вызывать процедуры на удаленном хосте. Причем при помощи XML-RPC можно абстрагироваться от конкретного языка программирования за счет использования общепринятых типов данных (строки, числа, логические значения и т.п.). В языке Python вызов удаленной функции по синтаксису ничем не отличается от вызова обычной функции:
А вот как выглядит XML-RPC-сервер (для того чтобы попробовать пример выше, необходимо сначала запустить сервер):
С помощью XML-RPC (а этот протокол достаточно «легковесный» среди других подобных протоколов) приложения могут общаться друг с другом на понятном им языке вызова функций с параметрами основных общепринятых типов и такими же возвращаемыми значениями. Преимуществом же Python является удобный синтаксис вызова удаленных функций.
Разумеется, это только пример. При реальном использовании необходимо позаботиться, чтобы XML-RPC сервер отвечал требованиям безопасности. Кроме того, сервер лучше делать многопоточным, чтобы он мог обрабатывать несколько потоков одновременно. Для многопоточности (она будет обсуждаться в отдельной лекции) не нужно многое переделывать: достаточно определить свой класс, скажем, ThreadingXMLRPCServer , в котором вместо SocketServer.TCPServer использовать SocketServer.ThreadingTCPServer . Это предлагается в качестве упражнения. Наводящий вопрос: где находится определение класса SimpleXMLRPCServer ?
Заключение
В этой лекции на практических примерах и сведениях из документации были показаны возможности, которые дает стандартный Python для работы в Интернете. Из сценария на Python можно управлять соединением на уровне сокетов, а также использовать модули для конкретного сетевого протокола или набора протоколов. Для работы с сокетами служит модуль socket , а модули для высокоуровневых протоколов имеют такие названия как smtplib , poplib , httplib и т.п. Для работы с системой WWW можно использовать модули urllib , urllib2 , urlparse . Указанные модули рассмотрены с точки зрения типичного применения. Для решения нестандартных задач лучше обратиться к другим источникам: документации, исходному коду модулей, поиску в Интернете. В этой лекции говорилось и о серверной составляющей высокоуровневых сетевых протоколов. В качестве примера приведена клиент-серверная пара для протокола XML-RPC. Этот протокол создан на основе HTTP, но служит специальной цели.
Учимся читать код, изучая стандартную библиотеку Python

Итак, вы уже продвинутый новичок — вы изучили основы Python и способны решать реальные задачи.
Вы уже отходите от просмотра туториалов и чтения блогов; наверно, уже ощущаете, что в них излагаются одномерные решения простых придуманных задач; вероятно, вместо решения этой конкретной задачи вы хотите совершенствоваться в решении задач в целом.
Наверно, вы слышали, что нужно нарабатывать понимание чтением и написанием больших объёмов кода. Это правда.
Но какой же код нужно читать?
«Просто читай то, что нравится». А если вы не знаете, что вам нравится? А если вам не нравится что-то правильное?
Или хуже того — если вам нравится что-то неправильное и из-за этого у вас выработаются вредные привычки?
В конечном итоге, для этого ведь необходимо понимание… Но именно его мы и стремимся обрести.
«На GitHub куча проектов — выберите понравившийся и изучайте, как его реализовали разработчики». Однако самые успешные проекты довольно объёмны — с чего начинать?
И даже если вы знаете, с чего начинать, не всегда очевидно, как разработчики пришли к своему решению.
Да, вы видите код своими глазами, но он не говорит вам о том, почему разработчики написали его так, чего они не делали и как они рассуждали о проекте в целом.
Другими словами, из самого кода неочевидно, какой была философия его проектирования, и какие варианты решений разработчики рассматривали, прежде чем остановиться на конкретной реализации.
В этой статье мы рассмотрим некоторые модули стандартной библиотеки Python.
Примечание о стандартной библиотеке
В целом, стандартная библиотека Python неидеальна для изучения «хорошего» стиля.
Хотя все её модули полезны, они не особо однородны:
- их писали разные авторы;
- некоторые из них старые (стиль Python 10-20 лет назад был другим);
- им нужно было сохранять обратную совместимость (то есть невозможно провести рефакторинг багов и вносить крупные изменения в API).
Мы рассмотрим как раз некоторые из них.
Если игнорировать стиль, у стандартной библиотеки можно многому научиться, ведь она решает реальные задачи множества разных разработчиков.
Любопытно изучить различия в возможностях stdlib и её новых внешних альтернатив — разница между ними демонстрирует дефицит, который испытывают разработчики (ведь в противном случае они бы не заморачивались созданием альтернативы). Хорошим примером этого является разница между urllib и requests .
Как читать модули
Приблизительно в таком порядке:
- Познакомьтесь с библиотекой как пользователь: прочитайте документацию, поэкспериментируйте с примерами.
- Прочитайте соответствующее Python Enhancement Proposal (PEP). Интересное обычно содержится в разделах Abstract, Rationale, Design Decisions, Discussion и Rejected Ideas.
- Прочитайте код; ссылка на него приведена в начале каждой страницы документации.
statistics
Модуль statistics добавляет в стандартную библиотеку статистические функции; он не создавался в качестве конкурента таких библиотек, как NumPy , а «находится на уровне построителя графиков и научного калькулятора».
Он был внедрён в PEP 450. Если вы незнакомы с этим предложением, то это очень любопытное чтиво:
- В разделе Rationale предложение сравнивается с NumPy и самодельными решениями; он особенно хорошо демонстрирует, что и почему было добавлено в стандартную библиотеку.
- Также там есть раздел Design Decisions, в котором объясняется, какой была общая философия проектирования; в разделах Discussion и FAQ тоже есть интересные подробности.
«Большая часть документации предназначена для читателей, понимающих базовые концепции, но которые могут не знать (например), какую дисперсию им стоит использовать [. ] Однако документация избегает скучных математических подробностей».
Код относительно прост, а когда это не так, то в нём есть комментарии и ссылки на подробные объяснения или статьи. Это может быть полезным, если вы изучаете все эти концепции и вам проще читать код, чем математическиe условные обозначения.
pathlib
Модуль pathlib обеспечивает простую иерархию классов для работы с путями файловой системы; он является высокоуровневой альтернативой os.path .
Модуль был внедрён в PEP 428. Большинство примеров используется для иллюстрации лежащей в основе модуля философии, а код оставлен в качестве спецификации.
Код хорошо читается по следующим причинам:
- Вероятно, вы уже знакомы с этой тематикой; даже если вы не пользовались раньше pathlib , то могли работать с os.path , или с похожей библиотекой в каком-то другом языке.
- Это хорошее объектно-ориентированное решение. Оно использует объектно-ориентированное программирование с абстрактными (читай: изобретёнными) концепциями, чтобы улучшить структуру кода и его многократное использование. Наверно, это гораздо лучший пример, чем старый Animal–Dog–Cat–Duck–speak().
- Это хорошая тема для сравнительного изучения: pathlib и os.path решают одну задачу, однако в совершенно разных стилях программирования. Кроме того, существовало ещё одно предложение, которое было отклонено, а ещё есть не меньше пяти похожих библиотек; pathlib позаимствовал что-то от каждой из них.
dataclasses
Модуль dataclasses снижает объём бойлерплейта при написании классов, генерируя специальные методы наподобие __init__ и __repr__ . (См. в качестве введения этот туториал, потому что в нём используются гораздо более конкретные примеры, чем в официальной документации.)
Он был внедрён в PEP 557 в качестве упрощённой версии attrs . Раздел Specification схож с документацией; интересные вещи встречаются в Rationale, Discussion и Rejected Ideas.
Кроме того, это отличный пример метапрограммирования; этот аспект подробно рассматривается в докладке Реймонда Хеттингера Dataclasses: The code generator to end all code generators. [Слайды с доклада в HTML и PDF.] Если у вас возникли проблемы с пониманием кода, то сначала посмотрите доклад; для меня оказалось довольно полезным объяснение генерируемого кода.
Бонус: graphlib
Модуль graphlib был добавлен в Python 3.9, и на данный момент содержит только одну вещь: реализацию алгоритма топологической сортировки (вот описание того, что это такое, и почему он полезен).
Он появился не через PEP; однако у него есть issue со множеством комментариев от разных разработчиков ядра, в том числе Реймонда Хеттингера и Тима Питерса (известного своим «Дзен языка Python»).
Так как это, по сути, решённая задача, в обсуждениях рассматривается API: куда его вставлять, кто должен его вызывать, как представлять входные и выходные данные, как одновременно обеспечить простоту использования и гибкость.
В обсуждении пытаются примирить два различных способа использования модуля:
- Вот граф, верни мне все узлы в топологическом порядке.
- Вот граф, верни мне все узлы, которые можно обработать прямо сейчас (или потому, что у них нет зависимостей, или потому, что их зависимости уже обработаны). Это полезно для распараллеливания работы, например, для скачивания и установки пакетов, зависимых от других пакетов.
По сравнению с обсуждением issue, сам код очень мал — меньше 250 строк, и в основном состоит из комментариев и документации.
На правах рекламы
Серверы для разработчиков и не только! Дешёвые VDS на базе новейшего «железа» для размещения проектов любой сложности, от корпоративных сетей и игровых проектов до лендингов и VPN.
Похожие публикации:
- Какое значение записано в переменной сразу после объявления
- Какое слово зарезервировано для обозначения анонимной функции
- Какой бренд телефона надежнее lenovo или asus
- Какой класс является родительским для потоков вывода данных
Язык программирования Python — тест 9

 (1) с помощью len(lines) можно вычислить длину сообщения в строках. Для вычисления длины сообщения в символах (точнее, в байтах) нужно просуммировать длину строк в списке lst (или взять octets ) 
 (2) в списке может не быть первого сообщения: необходимо это проверять 
 (3) делать quit() необязательно, он выполнится сам 
 (4) ошибок нет 
Номер 5
Какие утверждения о следующем фрагменте программы, работающей с POP3-сервером, правильные?import poplib, email p = poplib.POP3('pop3.SERVER') p.user('USERNAME', 'USERPASSWORD') response, lst, octets = p.list() # # обработка lst # . # p.quit()
 (1) отсутствуют две команды протокола POP3  
 (2) неправильный вызов метода user() : пароль задается в отдельной команде 
 (3) делать quit() необязательно, он выполнится сам 
 (4) ошибок нет 
Упражнение 4: Номер 1
Следующая программа считает, сколько процентов HTML-кода web-страницы занимают встроенные сценарии.import urllib, re SITE = "http://mail.ru" doc = urllib.open(SITE).read() script_re = re.compile("(?i)(?m)(?s)()") prc = sum([len(frag) for frag in script_re.findall(doc)]) / float(len(doc)) * 100 print "%.0f%%" % prc Какие ошибки допущены в этой программе?
 (1) в четвертой строке вместо script_re.findall(doc) нужно использовать script_re.findall(«\n».join(doc))  
 (2) в третьей строке должно быть urllib.urlopen , а не urllib.open  
 (3) в третьей строке не нужно использовать read()  
 (4) ошибок нет 
Номер 2
Какие утверждения о следующей программе (вычисляющей время загрузки сайтов из списка) верные?import urllib, time SITES = ["http://ya.ru", "http://yandex.ru", "http://www.google.ru"] for site in SITES: t1 = time.time() u = urllib.urlopen(site) doc = u.read() total = time.time()-t1 clen = int(u.info()['Content-Length']) print site, len(u), clen, total
 (1) u.info() может не содержать Content-Length : нужно предусмотреть try-except  
 (2) в последней строке вместо len(u) нужно использовать len(doc)  
 (3) метод для открытия URL не urllib.urlopen() , а urllib.open()  
 (4) серьезных замечаний и ошибок нет 
Номер 3
Какие утверждения о следующей программе (вычисляющей время загрузки сайтов из списка) верные?import urllib, time SITES = ["http://ya.ru", "http://yandex.ru", "http://www.google.ru"] for site in SITES: t1 = time.time() u = urllib.urlopen(site) doc = u.read() total = time.time()-t1 clen = int(u.info()['Content-Length']) print site, len(doc), clen, total
 (1) u.info() может не содержать Content-Length : нужно предусмотреть try-except  
 (2) метод для открытия URL не urllib.urlopen() , а urllib.open()  
 (3) в последней строке вместо len(doc) нужно использовать len(u)  
 (4) серьезных замечаний и ошибок нет 
Номер 4
Что может быть на местеQQQдля корректного формирования запроса с множественными значениями?import urllib enc_data = urllib.urlencode(QQQ) f = urllib.urlopen("http://searchengine.com/search" + "?" + enc_data)
 (1) [(«n», «1»), («n», «3»), («n», «4»), («button», «Hello»),]  
 (2)  
 (3) n=»1″, n=»3″, n=»4″, button=»Hello»  
 (4) [«n», «1», «n», «3», «n», «4», «button», «Hello»,]  
Номер 5
Что получится в результате вычисления следующего выражения:urllib.quote("a = b + c")
 (1) ‘a%20=%20b%20+%20c’  
 (2) ‘a%20=%20b%20%2B%20c’  
 (3) ‘a%20%3D%20b%20%2B%20c’  
 (4) ‘a+%3D+b+%2B+c’  
Упражнение 5: Номер 1
Как использовать XML-RPC сервер из Python-программы с помощью модуля xmlrpclib?
 (1) создать объект-подключение вызовом ServerProxy ; вызывать метод call этого объекта 
 (2) создать объект-подключение вызовом ServerProxy ; вызывать метод этого объекта, соответствующий названию зарегистрированной на удаленном сервере функции 
 (3) вызвать функцию xmlrpclib.make_call , аргументами которой указать URL, имя вызываемой функции и аргументы 
Номер 2
Какой модуль стандартной библиотеки Python позволяет работать с WWW на более низком уровне?
 (1) htmllib  
 (2) urlparse  
 (3) httplib  
 (4) urllib2  
Номер 3
Какой модуль стандартной библиотеки Python обеспечивает большую, чем urllib, дополнительную высокоуровневую функциональность при работе с WWW?
 (1) htmllib  
 (2) urlparse  
 (3) httplib  
 (4) urllib2  
Номер 4
Какова структура URL согласно RFC 2396?
 (1) scheme://netloc/path?query#fragment  
 (2) scheme://netloc/path;parameters?query  
 (3) scheme://netloc/path;parameters?query#fragment  
 (4) scheme://netloc/path?query#fragment;parameters  
Номер 5
Чему будет равен результат выполненияurlparse.urlsplit("http://google.com/search?q=Python#1") ?
