Содержание страницы
20.5. urllib – Открытие произвольных ресурсов по URL¶urllib – Open arbitrary resources by URL
Примечание
Модуль urllib разделён на части и переименован в Python 3 в urllib.request, urllib.parse и urllib.error. Инструмент 2to3 автоматически адаптирует импорты при преобразовании исходников в Python 3. Также обратите внимание, что функция urllib.request.urlopen() в Python 3 эквивалентна urllib2.urlopen(), а urllib.urlopen() удалена.
Данный модуль предоставляет высокоуровневый интерфейс для получения данных через Всемирную паутину. В частности, функция urlopen() похожа на встроенную функцию open(), но принимает универсальные указатели ресурсов (URL) вместо имён файлов. Имеются некоторые ограничения: она может открывать URL только для чтения, и операции поиска (seek) недоступны.
См. также
Для высокоуровневого интерфейса HTTP-клиента рекомендуется пакет Requests.
Изменено в версии 2.7.9: Для HTTPS URI urllib по умолчанию выполняет все необходимые проверки сертификатов и имён хостов.
Предупреждение
Для версий Python ранее 2.7.9 urllib не проверяет сертификаты серверов для HTTPS URI. Используйте на свой страх и риск!
20.5.1. Высокоуровневый интерфейс¶High-level interface
-
urllib.urlopen(url[, data[, proxies[, context]]])¶ Открывает сетевой объект, обозначенный URL, для чтения. Если URL не имеет идентификатора схемы или имеет
file:в качестве идентификатора схемы, открывается локальный файл (без универсальных новых строк); в противном случае открывается сокет к серверу где-то в сети. Если соединение не удалось, возникает исключениеIOError. Если всё прошло успешно, возвращается файлоподобный объект. Он поддерживает следующие методы:read(),readline(),readlines(),fileno(),close(),info(),getcode()иgeturl(). Также есть правильная поддержка протокола итератора. Одно предостережение: методread()при опущенном или отрицательном аргументе size может не дочитать до конца потока данных; в общем случае нет хорошего способа определить, что весь поток из сокета прочитан.За исключением методов
info(),getcode()иgeturl(), эти методы имеют тот же интерфейс, что и для файловых объектов – см. раздел Файловые объекты в данном руководстве. (Однако это не встроенный файловый объект, поэтому его нельзя использовать в тех немногих местах, где требуется настоящий встроенный файловый объект.)Метод
info()возвращает экземпляр классаmimetools.Message, содержащий метаинформацию, связанную с URL. Когда метод HTTP, эти заголовки являются теми, что возвращаются сервером в начале полученной HTML-страницы (включая Content-Length и Content-Type). Когда метод FTP, заголовок Content-Length будет присутствовать, если (как это теперь обычно) сервер вернул длину файла в ответ на запрос получения по FTP. Заголовок Content-Type будет присутствовать, если можно угадать MIME-тип. Когда метод local-file, возвращаемые заголовки будут включать Date, представляющую время последнего изменения файла, Content-Length с размером файла и Content-Type с предположением о типе файла. См. также описание модуляmimetools.Метод
geturl()возвращает реальный URL страницы. В некоторых случаях HTTP-сервер перенаправляет клиента на другой URL. Функцияurlopen()обрабатывает это прозрачно, но в некоторых случаях вызывающему коду нужно знать, на какой URL был перенаправлен клиент. Методgeturl()можно использовать для получения этого URL перенаправления.Метод
getcode()возвращает код состояния HTTP, отправленный с ответом, илиNone, если URL не является HTTP URL.Если url использует идентификатор схемы
http:, необязательный аргумент data может быть задан для указанияPOSTзапроса (обычно тип запросаGET). Аргумент data должен быть в стандартном формате application/x-www-form-urlencoded; см. функциюurlencode()ниже.Функция
urlopen()прозрачно работает с прокси, не требующими аутентификации. В среде Unix или Windows установите переменные окруженияhttp_proxyилиftp_proxyв URL, идентифицирующий прокси-сервер, перед запуском интерпретатора Python. Например ('%'– это приглашение командной строки):% http_proxy="http://www.someproxy.com:3128" % export http_proxy % python ...
Переменная окружения
no_proxyможет использоваться для указания хостов, которые не должны достигаться через прокси; если она установлена, это должен быть разделённый запятыми список суффиксов имён хостов, опционально с добавлением:port, напримерcern.ch,ncsa.uiuc.edu,some.host:8080.В среде Windows, если не заданы переменные окружения прокси, настройки прокси берутся из раздела Internet Settings реестра.
В среде Mac OS X
urlopen()получает информацию о прокси из OS X System Configuration Framework, которой можно управлять через панель Network в Системных настройках.В качестве альтернативы необязательный аргумент proxies можно использовать для явного указания прокси. Он должен быть словарём, отображающим имена схем в URL прокси; пустой словарь означает, что прокси не используются, а
None(значение по умолчанию) приводит к использованию настроек прокси из окружения, как обсуждалось выше. Например:# Используйте http://www.someproxy.com:3128 для HTTP-проксирования proxies = {'http': 'http://www.someproxy.com:3128'} filehandle = urllib.urlopen(some_url, proxies=proxies) # Не используйте никаких прокси filehandle = urllib.urlopen(some_url, proxies={}) # Используйте прокси из окружения – обе версии эквивалентны filehandle = urllib.urlopen(some_url, proxies=None) filehandle = urllib.urlopen(some_url)
Прокси, требующие аутентификации для использования, в настоящее время не поддерживаются; это считается ограничением реализации.
Параметр context может быть установлен в экземпляр
ssl.SSLContextдля настройки параметров SSL, которые используются, еслиurlopen()устанавливает HTTPS-соединение.Изменено в версии 2.3: Добавлена поддержка proxies.
Изменено в версии 2.6: Добавлен
getcode()к возвращаемому объекту и поддержка переменной окруженияno_proxy.Изменено в версии 2.7.9: Добавлен параметр context. Все необходимые проверки сертификатов и имён хостов выполняются по умолчанию.
Устарело с версии 2.6: Функция
urlopen()удалена в Python 3 в пользуurllib2.urlopen().
-
urllib.urlretrieve(url[, filename[, reporthook[, data[, context]]]])¶ Копирует сетевой объект, обозначенный URL, в локальный файл, если это необходимо. Если URL указывает на локальный файл или существует допустимая кэшированная копия объекта, объект не копируется. Возвращает кортеж
(filename, headers), где filename – это имя локального файла, в котором можно найти объект, а headers – то, что вернул методinfo()объекта, возвращённогоurlopen()(для удалённого объекта, возможно, кэшированного). Исключения те же, что и дляurlopen().Второй аргумент, если присутствует, задаёт местоположение файла для копирования (если отсутствует, местоположением будет временный файл с автоматически сгенерированным именем). Третий аргумент, если присутствует, является вызываемым объектом, который будет вызван один раз при установлении сетевого соединения и один раз после каждого последующего чтения блока. Вызываемый объект будет получать три аргумента: количество переданных блоков на данный момент, размер блока в байтах и общий размер файла. Третий аргумент может быть
-1на старых FTP-серверах, которые не возвращают размер файла в ответ на запрос получения.Если url использует идентификатор схемы
http:, необязательный аргумент data может быть задан для указанияPOSTзапроса (обычно тип запросаGET). Аргумент data должен быть в стандартном формате application/x-www-form-urlencoded; см. функциюurlencode()ниже.Параметр context может быть установлен в экземпляр
ssl.SSLContextдля настройки параметров SSL, которые используются, еслиurlretrieve()устанавливает HTTPS-соединение.Изменено в версии 2.5:
urlretrieve()будет вызыватьContentTooShortError, когда обнаружит, что объём доступных данных меньше ожидаемого (который равен размеру, указанному в заголовке Content-Length). Это может произойти, например, при прерывании загрузки.Content-Length рассматривается как нижняя граница: если есть ещё данные для чтения,
urlretrieve()читает больше данных, но если доступно меньше данных, он вызывает исключение.В этом случае вы всё ещё можете получить загруженные данные – они хранятся в атрибуте
contentэкземпляра исключения.Если заголовок Content-Length не был предоставлен,
urlretrieve()не может проверить размер загруженных данных и просто возвращает их. В этом случае остаётся только предполагать, что загрузка прошла успешно.Изменено в версии 2.7.9: Добавлен параметр context. Все необходимые проверки сертификатов и имен хостов выполняются по умолчанию.
-
urllib._urlopener¶ Публичные функции
urlopen()иurlretrieve()создают экземпляр классаFancyURLopenerи используют его для выполнения запрошенных действий. Чтобы переопределить это поведение, программисты могут создать подклассURLopenerилиFancyURLopener, а затем присвоить экземпляр этого класса переменнойurllib._urlopenerперед вызовом нужной функции. Например, приложения могут захотеть указать другой заголовок User-Agent, нежели тот, что определяетURLopener. Это можно сделать с помощью следующего кода:import urllib class AppURLopener(urllib.FancyURLopener): version = "App/1.7" urllib._urlopener = AppURLopener()
-
urllib.urlcleanup()¶ Очищает кэш, который мог быть накоплен предыдущими вызовами
urlretrieve().
20.5.2. Вспомогательные функции¶Utility functions
-
urllib.quote(string[, safe])¶ Заменяет специальные символы в строке с помощью экранирования
%xx. Буквы, цифры и символы'_.-'никогда не экранируются. По умолчанию эта функция предназначена для экранирования сегмента пути URL. Необязательный параметр safe задает дополнительные символы, которые не следует экранировать; его значение по умолчанию –'/'.Пример:
quote('/~connolly/')даёт'/%7econnolly/'.
-
urllib.quote_plus(string[, safe])¶ Как
quote(), но также заменяет пробелы знаками плюс, что требуется для квотирования значений HTML-форм при формировании строки запроса для URL. Знаки плюса в исходной строке экранируются, если они не включены в safe. Кроме того, значение по умолчанию для safe не равно'/'.
-
urllib.unquote(string)¶ Заменяет управляющие последовательности
%xxна эквивалентные им одиночные символы.Пример:
unquote('/%7Econnolly/')даёт'/~connolly/'.
-
urllib.unquote_plus(string)¶ Как
unquote(), но также заменяет знаки плюс пробелами, что требуется для расквотирования значений HTML-форм.
-
urllib.urlencode(query[, doseq])¶ Преобразует объект отображения (mapping) или последовательность кортежей из двух элементов в строку с «процентным кодированием», подходящую для передачи в качестве необязательного аргумента data функции
urlopen(), описанной выше. Это полезно для передачи словаря полей формы в запросеPOST. Результирующая строка представляет собой серию парkey=value, разделенных символами'&', где и ключ, и значение квотируются с помощьюquote_plus(). Когда в качестве аргумента query используется последовательность кортежей из двух элементов, первый элемент каждого кортежа – ключ, а второй – значение. Само значение может быть последовательностью, и в этом случае, если необязательный параметр doseq имеет значениеTrue, для каждого элемента последовательности-значения генерируются отдельные парыkey=value, разделенные'&'. Порядок параметров в закодированной строке будет соответствовать порядку кортежей параметров в последовательности. Модульurlparseпредоставляет функцииparse_qs()иparse_qsl(), которые используются для разбора строк запроса в структуры данных Python.
-
urllib.pathname2url(path)¶ Преобразует имя пути path из локального синтаксиса в форму, используемую в компоненте пути URL. Эта функция не создает полный URL. Возвращаемое значение уже будет закодировано с помощью функции
quote().
-
urllib.url2pathname(path)¶ Преобразует компонент пути path из URL с процентным кодированием в локальный синтаксис пути. Эта функция не принимает полный URL. Для декодирования path используется
unquote().
-
urllib.getproxies()¶ Эта вспомогательная функция возвращает словарь, сопоставляющий схему с URL прокси-сервера. Она сканирует переменные окружения с именем
<scheme>_proxy(без учета регистра) сначала во всех операционных системах, а если не находит их, ищет информацию о прокси в системных конфигурациях Mac OS X и в реестре Windows. Если существуют переменные окружения как в нижнем, так и в верхнем регистре (и они различаются), предпочтение отдается нижнему регистру.Примечание
Если установлена переменная окружения
REQUEST_METHOD, что обычно указывает на выполнение скрипта в CGI-среде, переменная окруженияHTTP_PROXY(в верхнем регистре_PROXY) будет проигнорирована. Это связано с тем, что эта переменная может быть вставлена клиентом через HTTP-заголовок «Proxy:». Если необходимо использовать HTTP-прокси в CGI-среде, либо явно используйтеProxyHandler, либо убедитесь, что имя переменной указано в нижнем регистре (или, по крайней мере, суффикс_proxy).
Примечание
Модуль urllib также предоставляет некоторые вспомогательные функции, такие как splittype, splithost и другие, для разбора URL на составные части. Однако рекомендуется использовать urlparse для разбора URL, а не эти функции напрямую. В Python 3 эти вспомогательные функции не доступны из модуля urllib.parse.
20.5.3. Объекты URL Opener¶URL Opener objects
-
class
urllib.URLopener([proxies[, context[, **x509]]])¶ Базовый класс для открытия и чтения URL. Если не требуется поддержка открытия объектов с использованием схем, отличных от
http:,ftp:илиfile:, вероятно, стоит использоватьFancyURLopener.По умолчанию класс
URLopenerотправляет заголовок User-Agent со значениемurllib/VVV, где VVV – это номер версииurllib. Приложения могут задать собственный заголовок User-Agent, создав подклассURLopenerилиFancyURLopenerи установив атрибут классаversionв соответствующее строковое значение в определении подкласса.Необязательный параметр proxies должен быть словарём, сопоставляющим имена схем с URL прокси. Пустой словарь полностью отключает прокси. Значение по умолчанию –
None; в этом случае используются настройки прокси из окружения (если они есть), как описано выше в определенииurlopen().Параметр context может быть экземпляром
ssl.SSLContext. Если он задан, то определяет настройки SSL, которые открыватель использует для HTTPS-соединений.Дополнительные именованные параметры, собранные в x509, могут использоваться для аутентификации клиента при использовании схемы
https:. Поддерживаются ключевые слова key_file и cert_file для указания SSL-ключа и сертификата; оба необходимы для поддержки аутентификации клиента.Объекты
URLopenerвозбуждают исключениеIOError, если сервер возвращает код ошибки.Изменено в версии 2.7.9: Добавлен параметр context. Все необходимые проверки сертификатов и имен хостов выполняются по умолчанию.
-
open(fullurl[, data])¶ Открывает fullurl, используя соответствующий протокол. Этот метод настраивает кеш и информацию о прокси, а затем вызывает соответствующий метод open с переданными аргументами. Если схема не распознана, вызывается
open_unknown(). Аргумент data имеет то же значение, что и аргумент data методаurlopen().
-
open_unknown(fullurl[, data])¶ Переопределяемый интерфейс для открытия неизвестных типов URL.
-
retrieve(url[, filename[, reporthook[, data]]])¶ Извлекает содержимое url и помещает его в filename. Возвращаемое значение – кортеж, состоящий из локального имени файла и либо объекта
mimetools.Message, содержащего заголовки ответа (для удаленных URL), либоNone(для локальных URL). Затем вызывающий код должен открыть и прочитать содержимое filename. Если filename не указан и URL ссылается на локальный файл, возвращается исходное имя файла. Если URL не локальный и filename не указан, имя файла генерируется функциейtempfile.mktemp()с суффиксом, соответствующим суффиксу последнего компонента пути исходного URL. Если задан reporthook, он должен быть функцией, принимающей три числовых параметра. Она будет вызываться после каждого блока данных, считанного из сети. reporthook игнорируется для локальных URL.Если url использует идентификатор схемы
http:, можно задать необязательный аргумент data для указания запроса типаPOST(обычно тип запроса –GET). Аргумент data должен иметь стандартный формат application/x-www-form-urlencoded; см. функциюurlencode()ниже.
-
-
class
urllib.FancyURLopener(...)¶ FancyURLopenerявляется подклассомURLopener, обеспечивающим стандартную обработку следующих HTTP-кодов ответа: 301, 302, 303, 307 и 401. Для перечисленных кодов 30x используется заголовок Location для получения фактического URL. Для кода 401 (требуется аутентификация) выполняется базовая HTTP-аутентификация. Для кодов 30x количество рекурсий ограничено значением атрибута maxtries, которое по умолчанию равно 10.Для всех остальных кодов ответа вызывается метод
http_error_default(), который можно переопределить в подклассах для соответствующей обработки ошибки.Примечание
В соответствии с буквой RFC 2616, ответы 301 и 302 на POST-запросы не должны автоматически перенаправляться без подтверждения пользователем. На практике браузеры всё же допускают автоматическое перенаправление таких ответов, заменяя POST на GET, и
urllibвоспроизводит это поведение.Параметры конструктора такие же, как для
URLopener.Примечание
При выполнении базовой аутентификации экземпляр
FancyURLopenerвызывает свой методprompt_user_passwd(). Реализация по умолчанию запрашивает у пользователя необходимую информацию на управляющем терминале. Подкласс может переопределить этот метод для обеспечения более подходящего поведения, если это необходимо.Класс
FancyURLopenerпредоставляет один дополнительный метод, который следует перегрузить для обеспечения соответствующего поведения:-
prompt_user_passwd(host, realm)¶ Возвращает информацию, необходимую для аутентификации пользователя на указанном хосте в заданной области безопасности. Возвращаемое значение должно быть кортежем
(user, password), который можно использовать для базовой аутентификации.Реализация запрашивает эту информацию на терминале; приложение должно переопределить этот метод, чтобы использовать подходящую модель взаимодействия в локальной среде.
-
-
exception
urllib.ContentTooShortError(msg[, content])¶ Это исключение возникает, когда функция
urlretrieve()обнаруживает, что объем загруженных данных меньше ожидаемого (указанного в заголовке Content-Length). Атрибутcontentхранит загруженные (и предположительно усеченные) данные.Новое в версии 2.5.
20.5.4. urllib Ограничения¶urllib Restrictions
В настоящее время поддерживаются только следующие протоколы: HTTP (версии 0.9 и 1.0), FTP и локальные файлы.
Функция кэширования
urlretrieve()отключена, пока я не найду время реализовать правильную обработку заголовков срока действия.Должна быть функция для проверки, находится ли определённый URL в кэше.
Для обратной совместимости, если URL указывает на локальный файл, но файл не удаётся открыть, URL интерпретируется заново с использованием протокола FTP. Это иногда может приводить к запутанным сообщениям об ошибках.
Функции
urlopen()иurlretrieve()могут вызывать произвольно длинные задержки при ожидании установки сетевого соединения. Это означает, что с помощью этих функций сложно построить интерактивный веб-клиент без использования потоков.Данные, возвращаемые
urlopen()илиurlretrieve(), представляют собой необработанные данные, возвращенные сервером. Это могут быть двоичные данные (например, изображение), обычный текст или HTML. Протокол HTTP предоставляет информацию о типе в заголовке ответа, который можно проверить, посмотрев на заголовок Content-Type. Если возвращенные данные – HTML, можно воспользоваться модулемhtmllibдля его разбора.Код, обрабатывающий протокол FTP, не может различить файл и каталог. Это может привести к неожиданному поведению при попытке чтения URL, указывающего на недоступный файл. Если URL заканчивается на
/, предполагается, что он ссылается на каталог, и будет обработан соответствующим образом. Но если попытка чтения файла приводит к ошибке 550 (означает, что URL не найден или недоступен, часто из-за прав доступа), то путь рассматривается как каталог, чтобы обработать случай, когда каталог указан URL, но завершающий/опущен. Это может привести к вводящим в заблуждение результатам при попытке получить файл, права на чтение которого делают его недоступным; FTP-код попытается прочитать его, завершится ошибкой 550, а затем выполнит вывод списка каталога для этого недоступного файла. Если требуется тонкий контроль, стоит рассмотреть использование модуляftplib, создание подклассаFancyURLopenerили изменение _urlopener в соответствии со своими потребностями.Этот модуль не поддерживает использование прокси, требующих аутентификации. Возможно, эта возможность будет реализована в будущем.
Хотя модуль
urllibсодержит (недокументированные) функции для разбора и сборки URL-строк, рекомендуемый интерфейс для работы с URL находится в модулеurlparse.
20.5.5. Примеры¶Examples
Вот пример сеанса, в котором используется метод GET для получения URL с параметрами:
>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
>>> print f.read()
В следующем примере вместо этого используется метод POST:
>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
>>> print f.read()
В следующем примере используется явно указанный HTTP-прокси, переопределяющий настройки окружения:
>>> import urllib
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.FancyURLopener(proxies)
>>> f = opener.open("http://www.python.org")
>>> f.read()
В следующем примере прокси не используются вовсе, переопределяя настройки окружения:
>>> import urllib
>>> opener = urllib.FancyURLopener({})
>>> f = opener.open("http://www.python.org/")
>>> f.read()