Urllib3 python 3 документация на русском: Библиотека Python Requests: документация на русском
Библиотека Python Requests: документация на русском
Быстрый старт в библиотеке Requests
Прежде чем начать, убедитесь, что установлена последняя версия Requests.
Для начала, давайте рассмотрим простые примеры.
Создание запроса
Импортируйте модуль Requests:
import requests
Попробуем получить веб-страницу. В этом примере давайте рассмотрим общий тайм-лайн GitHub:
r = requests.get('https://api.github.com/events')
Мы получили объект Response
с именем r
. С помощью этого объекта можно получить всю необходимую информацию.
Простой API Requests означает, что все формы HTTP запросов- очевидны. Ниже приведен пример того, как вы можете сделать запрос HTTP POST:
r = requests.post('https://httpbin.org/post', data = {'key':'value'})
Другие типы HTTP запросов такие как : PUT, DELETE, HEAD и OPTIONS так же очень легко выполнить:
r = requests.put('https://httpbin.org/put', data = {'key':'value'})
r = requests.delete('https://httpbin.org/delete')
r = requests.head('https://httpbin.org/get')
r = requests.options('https://httpbin.org/get')
Передача параметров в URL
Часто вам может понадобится отправить какие-то данные в строке запроса URL. Если вы настраиваете URL вручную, эти данные будут представлены в нем в виде пар ключ/значение после знака вопроса. Например, httpbin.org/get?key=val. Requests позволяет передать эти аргументы в качестве словаря, используя аргумент params
. Если вы хотите передать key1=value1
и key2=value2
ресурсу httpbin.org/get, вы должны использовать следующий код:
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('https://httpbin.org/get', params=payload)
Как видно, URL был закодирован правильно:
>>> print(r.url)
http://httpbin.org/get?key2=value2&key1=value1
Подписывайтесь на телеграм каналы
Ключ словаря, значение которого None
не будет добавлен в строке запроса URL.
Вы можете передать список параметров в качестве значения:
>>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> r = requests.get('https://httpbin.org/get', params=payload)
>>> print(r.url)
http://httpbin.org/get?key1=value1&key2=value2&key2=value3
Содержимое ответа (response)
Мы можем прочитать содержимое ответа сервера. Рассмотрим снова тайм-лайн GitHub:
>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...
Requests будет автоматически декодировать содержимое ответа сервера. Большинство кодировок unicode
декодируются без проблем.
Когда вы делаете запрос, Requests делает предположение о кодировке, основанное на заголовках HTTP. Эта же кодировка текста, используется при обращение к r.text
. Можно узнать, какую кодировку использует Requests, и изменить её с помощью r.encoding
:
>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'
Если вы измените кодировку, Requests будет использовать новое значение r.encoding
всякий раз, когда вы будете использовать r.text
. Вы можете сделать это в любой ситуации, где нужна более специализированная логика работы с кодировкой содержимого ответа. Например, в HTML
и XML
есть возможность задавать кодировку прямо в теле документа. В подобных ситуациях вы должны использовать r.content
, чтобы найти кодировку, а затем установить r.encoding
. Это позволит вам использовать r.text
с правильной кодировкой.
Requests может также использовать пользовательские кодировки в случае, если в них есть потребность. Если вы создали свою собственную кодировку и зарегистрировали ее в модуле codecs, используйте имя кодека в качестве значения r.encoding
.
Бинарное содержимое ответа
Вы можете также получить доступ к телу ответа в виде байтов для не текстовых ответов:
>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...
Передача со сжатием gzip
и deflate
автоматически декодируются для вас.
Например, чтобы создать изображение на основе бинарных данных, возвращаемых при ответе на запрос, используйте следующий код:
from PIL import Image
from io import BytesIO
i = Image.open(BytesIO(r.content))
Содержимое ответа в JSON
Если вы работаете с данными в формате JSON, воспользуйтесь встроенным JSON декодером:
>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
Если декодирование в JSON не удалось, r.json()
вернет исключение. Например, если ответ с кодом 204 (No Content), или на случай если ответ содержит не валидный JSON, попытка обращения к r.json()
будет возвращать ValueError: No JSON object could be decoded
.
Следует отметить, что успешный вызов r.json()
не указывает на успешный ответ сервера. Некоторые серверы могут возвращать объект JSON при неудачном ответе (например, сведения об ошибке HTTP 500). Такой JSON будет декодирован и возвращен. Для того, чтобы проверить успешен ли запрос, используйте r.raise_for_status()
или проверьте какой r.status_code
.
Необработанное содержимое ответа
В тех редких случаях, когда вы хотите получить доступ к “сырому” ответу сервера на уровне сокета, обратитесь к r.raw
. Если вы хотите сделать это, убедитесь, что вы указали stream=True
в вашем первом запросе. После этого вы уже можете проделать следующее:
>>> r = requests.get('https://api.github.com/events', stream=True)
>>> r.raw
<urllib3.response.HTTPResponse object at 0x101194810>
>>> r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
Однако, можно использовать подобный код как шаблон, чтобы сохранить результат в файл:
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
Использование r.iter_content
обработает многое из того, с чем бы вам пришлось иметь дело при использовании r.raw
напрямую. Для извлечения содержимого при потоковой загрузке, используйте способ, описанный выше. Обратите внимание, что chunk_size
можно свободно скорректировать до числа, которое лучше подходит в вашем случае.
Важное замечание об использовании
Response.iter_content
иResponse.raw
.Response.iter_content
будет автоматически декодироватьgzip
иdeflate
.Response.raw
— необработанный поток байтов, он не меняет содержимое ответа. Если вам действительно нужен доступ к байтам по мере их возврата, используйтеResponse.raw
.
Пользовательские заголовки
Если вы хотите добавить HTTP заголовки в запрос, просто передайте соответствующий dict
в параметре headers
.
Например, мы не указали наш user-agent
в предыдущем примере:
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)
Заголовкам дается меньший приоритет, чем более конкретным источникам информации. Например:
- Заголовки авторизации, установленные с помощью headers= будут переопределены, если учетные данные указаны
.netrc
, которые, в свою очередь переопределены параметромauth=
. - Заголовки авторизации будут удалены при редиректе.
- Заголовки авторизации с прокси будут переопределены учетными данными прокси-сервера, которые указаны в вашем URL.
- Заголовки Content-Length будут переопределены, когда вы определите длину содержимого.
Кроме того, запросы не меняют свое поведение вообще, основываясь на указанных пользовательских заголовках.
Значения заголовка должны быть
string, bytestring или unicode
. Хотя это разрешено, рекомендуется избегать передачи значений заголовковunicode
.
Более сложные POST запросы
Часто вы хотите послать некоторые form-encoded
данные таким же образом, как это делается в HTML форме. Для этого просто передайте соответствующий словарь в аргументе data
. Ваш словарь данных в таком случае будет автоматически закодирован как HTML форма, когда будет сделан запрос:
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("https://httpbin.org/post", data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
Аргумент data
также может иметь несколько значений для каждого ключа. Это можно сделать, указав data
в формате tuple
, либо в виде словаря со списками в качестве значений. Особенно полезно, когда форма имеет несколько элементов, которые используют один и тот же ключ:
>>> payload_tuples = [('key1', 'value1'), ('key1', 'value2')]
>>> r1 = requests.post('https://httpbin.org/post', data=payload_tuples)
>>> payload_dict = {'key1': ['value1', 'value2']}
>>> r2 = requests.post('https://httpbin.org/post', data=payload_dict)
>>> print(r1.text)
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}
>>> r1.text == r2.text
True
Бывают случаи, когда нужно отправить данные не закодированные методом form-encoded
. Если вы передадите в запрос строку вместо словаря, эти данные отправятся в не измененном виде.
К примеру, GitHub API v3 принимает закодированные JSON POST/PATCH данные:
import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload))
Вместо того, чтобы кодировать dict
, вы можете передать его напрямую, используя параметр json
(добавленный в версии 2.4.2), и он будет автоматически закодирован:
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
r = requests.post(url, json=payload)
Обратите внимание, параметр json
игнорируется, если передаются data
или files
.
Использование параметра json
в запросе изменит заголовок Content-Type на application/json.
POST отправка Multipart-Encoded файла
Запросы упрощают загрузку файлов с многостраничным кодированием (Multipart-Encoded) :
>>> url = 'https://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "<censored...binary...data>"
},
...
}
Вы можете установить имя файла, content_type и заголовки в явном виде:
>>> url = 'https://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "<censored...binary...data>"
},
...
}
Можете отправить строки, которые будут приняты в виде файлов:
>>> url = 'https://httpbin.org/post'
>>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "some,data,to,send\\nanother,row,to,send\\n"
},
...
}
В случае, если вы отправляете очень большой файл как запрос multipart/form-data, возможно понадобиться отправить запрос потоком. По умолчанию, requests не поддерживает этого, но есть отдельный пакет, который это делает — requests-toolbelt
. Ознакомьтесь с документацией toolbelt для получения более детальной информации о том, как им пользоваться.
Для отправки нескольких файлов в одном запросе, обратитесь к расширенной документации (EN).
Предупреждение!
Настоятельно рекомендуется открывать файлы в бинарном режиме. Это связано с тем, что запросы могут пытаться предоставить для вас заголовок Content-Length, и если это значение будет установлено на количество байтов в файле будут возникать ошибки, при открытии файла в текстовом режиме.
Коды состояния ответа
Мы можем проверить код состояния ответа:
>>> r = requests.get('https://httpbin.org/get')
>>> r.status_code
200
У requests есть встроенный объект вывода кодов состояния:
>>> r.status_code == requests.codes.ok
True
Если мы сделали неудачный запрос (ошибка 4XX или 5XX), то можем вызвать исключение с помощью r.raise_for_status():
>>> bad_r = requests.get('https://httpbin.org/status/404')
>>> bad_r.status_code
404
>>> bad_r.raise_for_status()
Traceback (most recent call last):
File "requests/models.py", line 832, in raise_for_status
raise http_error
requests.exceptions.HTTPError: 404 Client Error
Но если status_code
для r
оказался 200, то когда мы вызываем raise_for_status()
мы получаем:
>>> r.raise_for_status()
None
Заголовки ответов
Мы можем просматривать заголовки ответа сервера, используя словарь Python:
>>> r.headers
>
{
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json'
}
Это словарь особого рода, он создан специально для HTTP заголовков. Согласно с RFC 7230, имена заголовков HTTP нечувствительны к регистру:
Теперь мы можем получить доступ к заголовкам с большми буквами или без, если захотим:
>>> r.headers['Content-Type']
'application/json'
>>> r.headers.get('content-type')
'application/json'
Cookies
Если в запросе есть cookies, вы сможете быстро получить к ним доступ:
>>> url = 'https://example.com/some/cookie/setting/url'
>>> r = requests.get(url)
>>> r.cookies['example_cookie_name']
'example_cookie_value'
Чтобы отправить собственные cookies на сервер, используйте параметр cookies:
>>> url = 'https://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')
>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'
Cookies возвращаются в RequestsCookieJar, который работает как dict, но также предлагает более полный интерфейс, подходящий для использования в нескольких доменах или путях. Cookie jars могут также передаваться в запросы:
>>> jar = requests.cookies.RequestsCookieJar()
>>> jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
>>> jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
>>> url = 'https://httpbin.org/cookies'
>>> r = requests.get(url, cookies=jar)
>>> r.text
'{"cookies": {"tasty_cookie": "yum"}}'
Редиректы и история
По умолчанию Requests будет выполнять редиректы для всех HTTP глаголов, кроме HEAD.
Мы можем использовать свойство history
объекта Response, чтобы отслеживать редиректы .
Список Response.history содержит объекты Response, которые были созданы для того, чтобы выполнить запрос. Список сортируется от более ранних, до более поздних ответов.
Например, GitHub перенаправляет все запросы HTTP на HTTPS:
>>> r = requests.get('https://github.com')
>>> r.url
'https://github.com/'
>>> r.status_code
200
>>> r.history
[<Response [301]>]
Если вы используете GET, OPTIONS, POST, PUT, PATCH или DELETE, вы можете отключить обработку редиректа с помощью параметра allow_redirects
:
>>> r = requests.get('https://github.com', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]
Если вы используете HEAD, вы также можете включить редирект:
>>> r = requests.head('https://github.com', allow_redirects=True)
>>> r.url
'https://github.com/'
>>> r.history
[<Response [301]>]
Тайм-ауты
Вы можете сделать так, чтобы Requests прекратил ожидание ответа после определенного количества секунд с помощью параметра timeout
:
Почти весь производственный код должен использовать этот параметр почти во всех запросах. Несоблюдение этого требования может привести к зависанию вашей программы:
>>> requests.get('https://github.com', timeout=0.001)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
Timeout это не ограничение по времени полной загрузки ответа. Исключение возникает, если сервер не дал ответ за timeout секунд (точнее, если ни одного байта не было получено от основного сокета за timeout секунд).
Ошибки и исключения
В случае неполадок в сети (например, отказа DNS, отказа соединения и т.д.), Requests вызовет исключение ConnectionError
. Response.raise_for_status() вызовет HTTPError
если в запросе HTTP возникнет статус код ошибки.
Если выйдет время запроса, вызывается исключение Timeout
.
Если запрос превышает заданное значение максимального количества редиректов, то вызывают исключение TooManyRedirects
.
Все исключения, которые вызывает непосредственно Requests унаследованы от requests.exceptions.RequestException
.
Руководство по работе с HTTP в Python. Библиотека requests
24 Дек. 2015, Python,
307852 просмотров
Стандартная библиотека Python имеет ряд готовых модулей по работе с HTTP.
Если уж совсем хочется хардкора, то можно и сразу с socket поработать. Но у всех этих модулей есть один большой недостаток — неудобство работы.
Во-первых, большое обилие классов и функций. Во-вторых, код получается вовсе не pythonic. Многие программисты любят Python за его элегантность и простоту, поэтому и был создан модуль, призванный решать проблему существующих и имя ему requests или HTTP For Humans. На момент написания данной заметки, последняя версия библиотеки — 2.9.1. С момента выхода Python версии 3.5 я дал себе негласное обещание писать новый код только на Py >= 3.5. Пора бы уже полностью перебираться на 3-ю ветку змеюки, поэтому в моих примерах print отныне является функцией, а не оператором 🙂
Что же умеет requests?
Для начала хочется показать как выглядит код работы с http, используя модули из стандартной библиотеки Python и код при работе с requests. В качестве мишени для стрельбы http запросами будет использоваться очень удобный сервис httpbin.org
>>> import urllib.request
>>> response = urllib.request.urlopen('https://httpbin.org/get')
>>> print(response.read())
b'{\n "args": {}, \n "headers": {\n "Accept-Encoding": "identity", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.5"\n }, \n "origin": "95.56.82.136", \n "url": "https://httpbin.org/get"\n}\n'
>>> print(response.getheader('Server'))
nginx
>>> print(response.getcode())
200
>>>
Кстати, urllib.request это надстройка над «низкоуровневой» библиотекой httplib о которой я писал выше.
>>> import requests
>>> response = requests.get('https://httpbin.org/get')
>>> print(response.content)
b'{\n "args": {}, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.9.1"\n }, \n "origin": "95.56.82.136", \n "url": "https://httpbin.org/get"\n}\n'
>>> response.json()
{'headers': {'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'python-requests/2.9.1', 'Host': 'httpbin.org', 'Accept': '*/*'}, 'args': {}, 'origin': '95.56.82.136', 'url': 'https://httpbin.org/get'}
>>> response.headers
{'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Server': 'nginx', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Length': '237', 'Date': 'Wed, 23 Dec 2015 17:56:46 GMT'}
>>> response.headers.get('Server')
'nginx'
В простых методах запросов значительных отличий у них не имеется. Но давайте взглянем на работы с Basic Auth:
>>> import urllib.request
>>> password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
>>> top_level_url = 'https://httpbin.org/basic-auth/user/passwd'
>>> password_mgr.add_password(None, top_level_url, 'user', 'passwd')
>>> handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
>>> opener = urllib.request.build_opener(handler)
>>> response = opener.open(top_level_url)
>>> response.getcode()
200
>>> response.read()
b'{\n "authenticated": true, \n "user": "user"\n}\n'
>>> import requests
>>> response = requests.get('https://httpbin.org/basic-auth/user/passwd', auth=('user', 'passwd'))
>>> print(response.content)
b'{\n "authenticated": true, \n "user": "user"\n}\n'
>>> print(response.json())
{'user': 'user', 'authenticated': True}
А теперь чувствуется разница между pythonic и non-pythonic? Я думаю разница на лицо. И несмотря на тот факт, что requests ничто иное как обёртка над urllib3, а последняя является надстройкой над стандартными средствами Python, удобство написания кода в большинстве случаев является приоритетом номер один.
В requests имеется:
- Множество методов http аутентификации
- Сессии с куками
- Полноценная поддержка SSL
- Различные методы-плюшки вроде .json(), которые вернут данные в нужном формате
- Проксирование
- Грамотная и логичная работа с исключениями
О последнем пункте мне бы хотелось поговорить чуточку подробнее.
Обработка исключений в requests
При работе с внешними сервисами никогда не стоит полагаться на их отказоустойчивость. Всё упадёт рано или поздно, поэтому нам, программистам, необходимо быть всегда к этому готовыми, желательно заранее и в спокойной обстановке.
Итак, как у requests дела обстоят с различными факапами в момент сетевых соединений? Для начала определим ряд проблем, которые могут возникнуть:
- Хост недоступен. Обычно такого рода ошибка происходит из-за проблем конфигурирования DNS. (DNS lookup failure)
- «Вылет» соединения по таймауту
- Ошибки HTTP. Подробнее о HTTP кодах можно посмотреть здесь.
- Ошибки SSL соединений (обычно при наличии проблем с SSL сертификатом: просрочен, не является доверенным и т.д.)
Базовым классом-исключением в requests является RequestException. От него наследуются все остальные
- HTTPError
- ConnectionError
- Timeout
- SSLError
- ProxyError
И так далее. Полный список всех исключений можно посмотреть в requests.exceptions.
Timeout
В requests имеется 2 вида таймаут-исключений:
- ConnectTimeout — таймаут на соединения
- ReadTimeout — таймаут на чтение
>>> import requests
>>> try:
... response = requests.get('https://httpbin.org/user-agent', timeout=(0.00001, 10))
... except requests.exceptions.ConnectTimeout:
... print('Oops. Connection timeout occured!')
...
Oops. Connection timeout occured!
>>> try:
... response = requests.get('https://httpbin.org/user-agent', timeout=(10, 0.0001))
... except requests.exceptions.ReadTimeout:
... print('Oops. Read timeout occured')
... except requests.exceptions.ConnectTimeout:
... print('Oops. Connection timeout occured!')
...
Oops. Read timeout occured
ConnectionError
>>> import requests
>>> try:
... response = requests.get('http://urldoesnotexistforsure.bom')
... except requests.exceptions.ConnectionError:
... print('Seems like dns lookup failed..')
...
Seems like dns lookup failed..
HTTPError
>>> import requests
>>> try:
... response = requests.get('https://httpbin.org/status/500')
... response.raise_for_status()
... except requests.exceptions.HTTPError as err:
... print('Oops. HTTP Error occured')
... print('Response is: {content}'.format(content=err.response.content))
...
Oops. HTTP Error occured
Response is: b''
Я перечислил основные виды исключений, которые покрывают, пожалуй, 90% всех проблем, возникающих при работе с http. Главное помнить, что если мы действительно намерены отловить что-то и обработать, то это необходимо явно запрограммировать, если же нам неважен тип конкретного исключения, то можно отлавливать общий базовый класс RequestException и действовать уже от конкретного случая, например, залоггировать исключение и выкинуть его дальше наверх. Кстати, о логгировании я напишу отдельный подробный пост.
У блога появился свой Telegram канал, где я стараюсь делиться интересными находками из сети на тему разработки программного обеспечения. Велком, как говорится 🙂
Полезные «плюшки»
- httpbin.org очень полезный сервис для тестирования http клиентов, в частности удобен для тестирования нестандартного поведения сервиса
- httpie консольный http клиент (замена curl) написанный на Python
- responses mock библиотека для работы с requests
- HTTPretty mock библиотека для работы с http модулями
открытие URL-адресов, получение доступа к данным
От автора: Urllib — это модуль Python, который можно использовать для открытия URL-адресов. Он определяет функции и классы для обработки URL-адресов.
С помощью Python вы также можете получать и получать данные из Интернета, такие как XML, HTML, JSON и т. д. Вы также можете использовать Python для непосредственной работы с этими данными. В этом руководстве мы рассмотрим, как можно получать данные из Интернета. Например, здесь мы использовали URL-адрес видео guru99, и мы собираемся получить доступ к этому URL-адресу видео с помощью Python, а также вывести HTML-файл этого URL-адреса.
В этом руководстве мы рассмотрим:
Как открыть URL с помощью Urllib
Как в Python прочитать HTML-файл для URL-адреса
Бесплатный курс «Python. Быстрый старт»
Получите курс и узнайте, как создать программу для перевода текстов на Python
Получить курс
Как открыть URL с помощью Urllib
Перед тем, как запустить код для подключения к интернет-данным, нам импортировать модуль библиотеки URL или «urllib».
Импортируем urllib
Определяем основную функцию
Объявляем переменную webUrl
Затем вызываем функцию urlopen в библиотеке urllib
URL, который мы открываем — это руководство guru99 по YouTube
Далее мы собираемся вывести код результата
Код результата получается путем вызова функции getcode для созданной нами переменной webUrl
Мы собираемся преобразовать это в строку, чтобы ее можно было объединить со строкой «код результата»
Бесплатный курс «Python. Быстрый старт»
Получите курс и узнайте, как создать программу для перевода текстов на Python
Получить курс
Это будет обычный HTTP-код «200», указывающий, что http-запрос успешно обработан
Как в Python получить URL-адрес HTML-файла
Вы также можете прочитать файл HTML, используя «функцию чтения», и когда вы запустите код, файл HTML отобразится в консоли.
Вызовите функцию read для переменной webURL
Переменная Read позволяет читать содержимое файлов данных.
Считать все содержимое URL-адреса в переменную с именем data
Запустите код — он выведет данные в формате HTML
Вот полный код:
Пример Python 2
#
# читаем данные с URL-адреса и выводим их
#
import urllib2
def main():
# открываем соединение к URL-адресу с помощью urllib2
webUrl = urllib2.urlopen(«https://www.youtube.com/user/guru99com»)
#получаем код результата и выводим его
print «result code: » + str(webUrl.getcode())
# читаем данные с URL-адреса и выводим их data
= webUrl.read()
print data
if __name__ == «__main__»:
main()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # # читаем данные с URL-адреса и выводим их # import urllib2
def main(): # открываем соединение к URL-адресу с помощью urllib2 webUrl = urllib2.urlopen(«https://www.youtube.com/user/guru99com»)
#получаем код результата и выводим его print «result code: » + str(webUrl.getcode())
# читаем данные с URL-адреса и выводим их data = webUrl.read() print data if __name__ == «__main__»: main() |
Пример Python 3
#
# читаем данные с URL-адреса и выводим их
#
import urllib.request
# открываем соединение к URL-адресу с помощью urllib2
webUrl = urllib.request.urlopen(‘https://www.youtube.com/user/guru99com’)
# получаем код результата и выводим его
print («result code: » + str(webUrl.getcode()))
# читаем данные с URL-адреса и выводим их data = webUrl.read()
print (data)
# # читаем данные с URL-адреса и выводим их # import urllib.request # открываем соединение к URL-адресу с помощью urllib2 webUrl = urllib.request.urlopen(‘https://www.youtube.com/user/guru99com’)
# получаем код результата и выводим его print («result code: » + str(webUrl.getcode()))
# читаем данные с URL-адреса и выводим их data = webUrl.read() print (data) |
Источник: https://www.guru99.com
Редакция: Команда webformyself.
Бесплатный курс «Python. Быстрый старт»
Получите курс и узнайте, как создать программу для перевода текстов на Python
Получить курс
Библиотека Python Requests: продвинутая документация на русском
В этом материале описаны продвинутые функции библиотеки Requests.
Объекты Session
Объект Session
позволяет сохранять определенные параметры между запросами. Он же сохраняет куки всех запросов, сделанных из экземпляра Session
.
Объект Session
включает все методы основного API Requests.
Попробуем передать куки между запросами:
s = requests.Session()
s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("https://httpbin.org/cookies")
print(r.text)
Session
могут также использоваться для предоставления данных по умолчанию для методов запроса. Для этого их нужно передать в параметры объекта:
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
Любые словари, переданные методу запроса? будут объединены с заданными значениями уровня сессии. Параметры уровня методов перезаписывают параметры сессии.
Удалите значение из параметра словаря:
Иногда нужно будет не включать ключи уровня сессии в параметры словаря. Для этого необходимо установить значения ключаNone
в параметре уровня методов. Они будут пропускаться автоматически.
Все значения, содержащиеся в сессии, прямо доступны. Подробнее об этом в документации API Session.
Объекты запросов и ответов
Каждый раз при вызове запроса происходят две вещи. Во-первых, создается объект Request
, который будет направлен на сервер, чтобы сделать запрос или вернуть определенный ресурс. Во-вторых, когда библиотека получает ответ от сервера, генерируется объект Response
. Он содержит всю информацию, которую вернул сервер и оригинальный объект Request
. Вот простой запрос для получения крайне важной информации с серверов Википедии:
>>> r = requests.get('https://ru.wikipedia.org/wiki/Монти_Пайтон')
Подписывайтесь на телеграм каналы
Если нужно получить доступ к заголовкам, которые вернул сервер, делается следующее:
>>> r.headers
{'Date': 'Fri, 06 Mar 2020 10:40:21 GMT', 'Content-Type': 'text/html; charset=UTF-8',
'Server': 'mw1258.eqiad.wmnet', 'X-Powered-By': 'PHP/7.2.26-1+0~20191218.33+debian9~1.gbpb5a340+wmf1',
'X-Content-Type-Options': 'nosniff', 'P3P': 'CP="See [https://ru.wikipedia.org/wiki/Special:CentralAutoLogin/P3P](https://ru.wikipedia.org/wiki/Special:CentralAutoLogin/P3P) for more info."',
'Content-language': 'ru', 'Vary': 'Accept-Encoding,Cookie,Authorization',
'Last-Modified': 'Fri, 21 Feb 2020 10:40:21 GMT', 'Backend-Timing': 'D=181758 t=1583491220993575',
'X-ATS-Timestamp': '1583491221', 'Content-Encoding': 'gzip',
'X-Varnish': '1017342992 492505475', 'Age': '82909', 'X-Cache': 'cp3050 miss, cp3056 hit/43',
'X-Cache-Status': 'hit-front', 'Server-Timing': 'cache;desc="hit-front"',
'Strict-Transport-Security': 'max-age=106384710; includeSubDomains; preload',
'X-Client-IP': '111.111.111.1', 'Cache-Control': 'private, s-maxage=0, max-age=0, must-revalidate',
'Accept-Ranges': 'bytes', 'Content-Length': '41759', 'Connection': 'keep-alive'}
А если нужны те, что были направлены серверу, тогда сперва нужно получить доступ к запросу, а потом — к его заголовкам:
>>> r.request.headers
{'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
Подготовка запросов
При получении объекта Response
от вызова API или Session
, используется атрибут PreparedRequest
функции request
. В некоторых случаях над телом и заголовками (и чем угодно еще) можно будет провести дополнительную работу перед отправкой запроса. Простейший способ следующий:
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = req.prepare()
prepped.body = 'No, I want exactly this as the body.'
del prepped.headers['Content-Type']
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.status_code)
Поскольку с объектом Request
не происходит ничего особенного, его можно сразу подготовить и изменить объект PreparedRequest
. Затем он отправляется с остальными параметрами, которые вы бы отправили в requests.*
или Session.*
.
Однако этот код лишен кое-каких преимуществ использования объекта Session
. Если точнее, состояние уровня Session
, например куки, не будет применено к запросу. Чтобы получить PreparedRequest
с примененным состоянием, замените вызов к Request.prepare()
вызовом к Session.prepare_request()
:
from requests import Request, Session
s = Session()
req = Request('GET', url, data=data, headers=headers)
prepped = s.prepare_request(req)
prepped.body = 'Seriously, send exactly these bytes.'
prepped.headers['Keep-Dead'] = 'parrot'
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.status_code)
При использовании потока “prepared request” помните, что он не учитывает окружение. Это может привести к проблемам в том случае, если переменные окружения используются для изменения поведения запросов. Например: самозаверенные SSL-сертификаты, определенные в REQUESTS_CA_BUNDLE
, учитываться не будут. Результат — SSL: CERTIFICATE_VERIFY_FAILED
. Обойти это поведение можно, явно объединив настройки окружения с сессией:
from requests import Request, Session
s = Session()
req = Request('GET', url)
prepped = s.prepare_request(req)
settings = s.merge_environment_settings(prepped.url, {}, None, None, None)
resp = s.send(prepped, **settings)
print(resp.status_code)
Проверка сертификата SSL
Библиотека Requests может верифицировать SSL-сертификаты для HTTPS-запросов так же, как и браузер. Для проверки сертификата хоста, нужно просто добавить аргумент verify
:
>>> requests.get('https://kennethreitz.com', verify=True)
requests.exceptions.SSLError: hostname 'kennethreitz.com'
doesn't match either of '*.herokuapp.com', 'herokuapp.com'
Если такового нет или он недействителен, вернется ошибка SSLError. Но у Github, например, есть:
>>> requests.get('https://github.com', verify=True)
<Response [200]>
verify
можно передать и файлу CA_BUNDLE
для частных сертификатов. Или же настроить переменную среды REQUESTS_CA_BUNDLE
.
Библиотека может игнорировать проверку SSL-сертификатов, если значение verify
— False
.
>>> requests.get('https://kennethreitz.com', verify=False)
<Response [200]>
По умолчанию значение verify
— True
. Параметр подходит только для сертификатов хостов.
Можно также определить файл локального сертификата в виде пути или пары ключ-значение:
>>> requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key'))
<Response [200]>
Если указан неправильный путь или недействительный сертификат, произойдет следующее:
>>> requests.get('https://kennethreitz.com', cert='/wrong_path/server.pem')
SSLError: [Errno 336265225] _ssl.c:347: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
Работа с содержанием ответа
По умолчанию при запросе тело ответа загружается сразу же. Переписать это поведение и отсрочить загрузку тела ответа до того момента, пока не будет получен доступ к атрибуту Response.content
, можно с помощью параметра stream
:
tarball_url = 'https://github.com/kennethreitz/requests/tarball/master'
r = requests.get(tarball_url, stream=True)
Сейчас загружаются только заголовки ответа, а соединение остается открытым. Это позволяет сделать получение контента по условию:
if int(r.headers['content-length']) < TOO_LONG:
content = r.content
Можно и дальше контролировать процесс работы с помощью методов Response.iter_content
и Response.iter_lines
или чтения их из лежащей в основе библиотеки urllib3 urllib3.HTTPResponse
в Response.raw
.
Постоянное соединение
Благодаря urllib3 постоянное соединение поддерживается на 100% автоматически прямо в сессии. Любые запросы в сессии будут автоматически использовать соответствующее соединение.
Стоит отметить, что соединения сбрасываются и возвращаются в пул для повторного использовать только после чтения данных тела. Важно задать значение stream
равным False
или читать свойство property
объекта Response
.
Потоковые загрузки
Requests поддерживает потоковые загрузки, которые позволяют отправлять крупные потоки или файлы без их чтения прямо в память. Для этого нужно предоставить файловый объект в data
:
with open('massive-body') as f:
request.post('http://some.url/streamed', data=f)
Запросы для данных, разбитых на части (chunk-encoded)
Requests также поддерживает механизм передачи с разбиением на части для входящих и исходящих запросов. Для отправления такого нужно предоставить генератор (или любой итератор без определенной длины) в data
:
def gen():
yield 'hi'
yield 'there'
request.post('http://some.url/chunked', data=gen())
POST для нескольких файлов типа multipart
Можно отправить несколько файлов одним запросом. Например, предположим, необходимо загрузить файлы изображений в HTML-форму images
для нескольких файлов :
<input type="file" name="images" multiple="true" required="true"/>
Чтобы сделать это, просто представьте файлы в виде списка кортежей такого формата (form_field_name, file_info)
:
>>> url = 'https://httpbin.org/post'
>>> multiple_files = [
... ('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
... ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
>>> r = requests.post(url, files=multiple_files)
>>> r.text
{
...
'files': {'images': 'data:image/png;base64,iVBORw ....'}
'Content-Type': 'multipart/form-data; boundary=3131623adb2043caaeb5538cc7aa0b3a',
...
}
Предупреждение:
Рекомендуется открывать файлы в бинарном режиме. Это важно, потому чтоRequests
может попробовать предоставить заголовокContent-Length
. В таком случае значением будет количеством байт в файле. А ошибки возникнут, если открыть файл в текстовом режиме.
Хуки (перехват управления)
В Requests есть система хуков, которую можно использовать для управления частями процесса запроса или обработки событий.
Доступные хуки:
response
: ответ, сгенерированный из объектаRequest
.
Можно назначать функцию перехвата для каждого запроса, передавая словарь {hook_name: callback_function}
в параметр запроса hooks
:
hooks=dict(response=print_url)
callback_function
получит кусок данных в качестве первого аргумента.
def print_url(r):
print(r.url)
Если при выполнении обратного вызова произойдет ошибка, отобразится предупреждение.
Если функция вернет значение, предполагается, что оно должно заменить данные, которые были переданы. Когда функция не возвращает ничего, нет никакого эффекта.
Выведем некоторые аргументы метода запроса:
>>> requests.get('http://httpbin.org', hooks=dict(response=print_url))
http://httpbin.org
<Response [200]>
Собственная аутентификация
Requests позволяет указать собственный механизм аутентификации.
Любой вызываемый объект, передаваемый в качестве аргумента auth
методу запроса, может изменить запрос до его отправки.
Реализации аутентификации — это подклассы requests.auth.AuthBase
, и их легко определить. Requests предоставляет две общие схемы реализации аутентификации в requests.auth:HTTPBasicAuth
и HTTPDigestAuth
.
Представим, что есть веб-сервис, который отвечает только в том случае, если значение заголовка X-Pizza
— значение пароля. Такое маловероятно, но мало ли.
from requests.auth import AuthBase
class PizzaAuth(AuthBase):
"""Прикрепляет аутентификацию HTTP Pizza к данному объекту запроса."""
def __init__(self, username):
self.username = username
def __call__(self, r):
r.headers['X-Pizza'] = self.username
return r
Теперь можно сделать запрос с помощью PizzaAuth
:
>>> requests.get('http://pizzabin.org/admin', auth=PizzaAuth('kenneth'))
<Response [200]>
Потоковые запросы
С помощью requests.Response.iter_lines()
можно запросто перебирать потоковые API, такие как Twitter Streaming API.
Используем его для отслеживания ключа словаря requests
:
import requests
import json
r = requests.post('https://stream.twitter.com/1/statuses/filter.json',
data={'track': 'requests'}, auth=('username', 'password'), stream=True)
for line in r.iter_lines(decode_unicode=True):
if line:
print(json.loads(line))
Прокси
Если есть необходимость использовать прокси, можно настроить индивидуальные запросы с помощью аргумента proxies
для любого метода запроса:
import requests
proxies = {
"http": "10.10.1.10:3128",
"https": "10.10.1.10:1080",
}
requests.get("http://example.org", proxies=proxies)
Также их можно настроить с помощью переменных среды HTTP_PROXY
и HTTPS_PROXY
.
$ export HTTP_PROXY="10.10.1.10:3128"
$ export HTTPS_PROXY="10.10.1.10:1080"
$ python
>>> import requests
>>> requests.get("http://example.org")
Для использования HTTP Basic Auth (аутентификации) со своим прокси, используется синтаксис http://user:password@host/
:
proxies = {
"http": "http://user:[email protected]:3128/",
}
SOCKS
Новое в версии 2.10.0
В дополнение к базовым прокси HTTP Requests также поддерживает прокси с помощью протокола SOCKS. Это опциональная функция, требующая дополнительных библиотек. Их можно получить с помощью pip
:
$ pip install requests[socks]
После установки использовать прокси SOCKS так же просто, как и HTTP:
proxies = {
'http': 'socks5://user:pass@host:port',
'https': 'socks5://user:pass@host:port'
}
При использовании socks5
разрешение DNS работает на стороне клиента, а не на стороне прокси-сервера. Это работает в соответствии с curl, который использует схему, чтобы определять, на чьей стороне разрешать DNS. Если необходимо заниматься преобразованием на стороне прокси-сервера, тогда используется socks5h
.
Соответствие стандартам
Requests соответствует всем актуальным спецификациям и RFC (технические стандарты, применяемые в сети) там, где подобное соответствие не создает трудностей для пользователей. Такое внимание к спецификациям может привести к необычному поведению, которое покажется необычным для тех, кто не знаком с ними.
Кодировки
Когда вы получаете ответ, Requests предполагает, какую кодировку использовать для декодирования во время вызова метода Response.text
. Библиотека сначала проверит кодировку в заголовке HTTP, и если там ничего не указано, воспользуется charade
, чтобы попробовать угадать.
Она не будет вести себя подобным образом только в одном случае — если кодировка не указано явно, а значение Content-Type
— text
. В таком случае, согласно RFC 2616, кодировка по умолчанию — ISO-8859-1
. Библиотека следует этому правилу. Если вам требуется другая кодировка, вы можете вручную настроить свойство Response. encoding
или использовать сырой Response.content
.
Методы HTTP
Requests предоставляет доступ ко всем методам HTTP: GET, OPTIONS, HEAD, POST, PUT, PATCH, DELETE
. Далее будут детальные примеры того, как их использовать с GitHub API.
Начнем с самого популярного метода — GET
. GET
— это идемпотентный метод, который возвращает ресурс по заданному URL. Он используется для получения данных из определенного места. Пример — попытка получить информацию об определенном коммите из GitHub. Пусть будет коммит a050faf
. Это будет выглядеть вот так:
>>> import requests
>>> r = requests.get('https://api.github.com/repos/kennethreitz/requests/git/commits/a050faf084662f3a352dd1a941f2c7c9f886d4ad')
Нужно подтвердить, что GitHub ответил правильно. Если да — необходимо определить тип контента. Это делается следующим образом:
>>> if (r.status_code == requests.codes.ok):
... print(r.headers['content-type'])
...
application/json; charset=utf-8
Итак, GitHub возвращает JSON
. Можно использовать метод r.json
для парсинга его в объекты Python.
>>> commit_data = r.json()
>>> print(commit_data.keys())
['committer', 'author', 'url', 'tree', 'sha', 'parents', 'message']
>>> print(commit_data['committer'])
{'date': '2012-05-10T11:10:50-07:00', 'email': '[email protected]', 'name': 'Kenneth Reitz'}
>>> print(commit_data['message'])
makin' history
Пока что все просто. Но посмотрим, что еще есть в API GitHub. Можно просто почитать документацию, но еще интереснее, если просто поэкспериментировать с Requests. Используем метод OPTIONS
, чтобы увидеть какие еще методы HTTP поддерживаются для этого ресурса.
>>> verbs = requests.options(r.url)
>>> verbs.status_code
500
Оказывается, что у GitHub, как и у многих API, не реализован метод OPTIONS
. Так что придется все-таки использовать документацию. Но если бы метод OPTION
был реализован, он вернул бы примерно следующее.
>>> verbs = requests.options('http://a-good-website.com/api/cats')
>>> print(verbs.headers['allow'])
GET,HEAD,POST,OPTIONS
В документации указано, что единственные разрешенные методы для коммитов — POST
. Они создают новые коммиты. Но поскольку используется репозиторий Requests, лучше не делать туда бесполезные POST
. Вместо этого можно поиграть с функцией Issues.
Эта документация была добавлена в ответ на “Issue #482”. Возьмем ее в качестве примера.
>>> r = requests.get('https://api.github.com/repos/kennethreitz/requests/issues/482')
>>> r.status_code
200
>>> issue = json.loads(r.text)
>>> print(issue['title'])
Feature any http verb in docs
>>> print(issue['comments'])
3
Есть три комментария. Рассмотрим последний из них.
>>> r = requests.get(r.url + '/comments')
>>> r.status_code
200
>>> comments = r.json()
>>> print(comments[0].keys())
['body', 'url', 'created_at', 'updated_at', 'user', 'id']
>>> print(comments[2]['body'])
Probably in the "advanced" section
Можем сообщить автору, что он не прав. Но сперва узнаем, кто это.
>>> print(comments[2]['user']['login'])
kennethreitz
Теперь скажем этому kennethreitz
, что ему лучше отправляться в раздел для начинающих. Согласно документации API GitHub это делается с помощью метода POST.
>>> body = json.dumps({"body": "Sounds great! I'll get right on it!"})
>>> url = "https://api.github.com/repos/kennethreitz/requests/issues/482/comments"
>>> r = requests.post(url=url, data=body)
>>> r.status_code
404
Похоже, нужно авторизоваться. В Requests можно выполнить любой вид аутентификации, включая базовую.
>>> from requests.auth import HTTPBasicAuth
>>> auth = HTTPBasicAuth('[email protected]', 'not_a_real_password')
>>> r = requests.post(url=url, data=body, auth=auth)
>>> r.status_code
201
>>> content = r.json()
>>> print(content['body'])
Sounds great! I'll get right on it.
Теперь попробуем отредактировать сообщение. Для этого нужен метод PATCH
.
>>> print(content["id"])
5804413
>>> body = json.dumps({"body": "Sounds great! I'll get right on it once I feed my cat."})
>>> url = "https://api.github.com/repos/kennethreitz/requests/issues/comments/5804413"
>>> r = requests.patch(url=url, data=body, auth=auth)
>>> r.status_code
200
С баловством покончено. Используем DELETE
для удаления сообщения.
>>> r = requests.delete(url=url, auth=auth)
>>> r.status_code
204
>>> r.headers['status']
'204 No Content'
Напоследок можно посмотреть, как много запросов было использовано. Для этого нужно сделать запрос HEAD
к заголовкам и не скачивать целую страницу.
>>> r = requests.head(url=url, auth=auth)
>>> print(r.headers)
...
'x-ratelimit-remaining': '4995'
'x-ratelimit-limit': '5000'
...
Осталось написать программу на Python, которая бы использовала остальные 4995 запросов.
Заголовки Link
Многие API используют заголовки Link
. Они делают API более описательными и простыми в использования. GitHub используют пагинацию в своем API, например:
>>> url = 'https://api.github.com/users/kennethreitz/repos?page=1&per_page=10'
>>> r = requests.head(url=url)
>>> r.headers['link']
<https://api.github.com/users/kennethreitz/repos?page=2&per_page=10>; rel="next", <https://api.github.com/users/kennethreitz/repos?page=6&per_page=10>; rel="last"
Requests автоматически парсит эти ссылки и позволяет с легкостью их использовать.
>>> r.links["next"]
{'url': 'https://api.github.com/users/kennethreitz/repos?page=2&per_page=10', 'rel': 'next'}
>>> r.links["last"]
{'url': 'https://api.github.com/users/kennethreitz/repos?page=7&per_page=10', 'rel': 'last'}
Пользовательские HTTP-методы
Иногда вы будете работать с сервером, который по какой-то причине требует использовать методы HTTP за исключение базовых. Например, метод MKCOL, который используют сервера WEBDAV. Однако с ними также можно работать в Requests. В данном случае используется встроенный метод .request
. Например:
>>> r = requests.request('MKCOL', url, data=data)
>>> r.status_code
200
Таким образом можно использовать любой метод, разрешенный сервером.
Transport Adapters
Начиная с версии v1.0.0, Requests использует внутренний модульный дизайн. Одна из причин — внедрение Transport Adapters. Они предоставляют средство для определения методов взаимодействия с HTTP. В частности, позволяют применять настройку для каждого сервиса по отдельности.
Requests поставляются с одним таким Transport Adapter — HTTPAdapter
. Он предоставляет возможность взаимодействия с HTTP и HTTPS посредством библиотеки urllib3
из Requests по умолчанию. При инициализации Session
один из них «крепится» к объекту Session
HTTP, а второй — к HTTPS.
Requests дают возможность пользователям создавать и использовать собственные Transport Adapters с конкретной функциональностью. После создания Transport Adapter может быть прикреплен к объему Session вместе с указанием сервисов, к которым он должен применяться.
>>> s = requests.Session()
>>> s.mount('https://github.com/', MyAdapter())
Вызов mount
регистрирует экземпляр Transport Adapter в префиксе. После этого HTTP-запросы, сделанные с помощью этого Session
и URL которых начинается с этого префикса, будут использовать указанный Transport Adapter.
Многие подробности использования Transport Adapter лежат за рамками этого материала, но вы сможете разобраться лучше на следующем примере.
Пример: конкретная версия SSL
Разработчики Requests заранее определили, какая версия SSL будет использоваться по умолчанию в urllib3
. Обычно это работает так, как нужно, но иногда требуется подключиться к конечной точке, которая использует версию, не совместимую с той, что указана по умолчанию.
В этом случае можно задействовать Transport Adapter, используя большую часть существующей реализации HTTPAdapter
и добавив параметр ssl_version
, который передается через urllib3
. Настроим Transport Adapter, чтобы библиотека использовала SSLv3
:
from urllib3.poolmanager import PoolManager
from requests.adapters import HTTPAdapter
class Ssl3HttpAdapter(HTTPAdapter):
""""Transport adapter" который позволяет использовать SSLv3."""
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_version=ssl.PROTOCOL_SSLv3)
Блокирующий или не-блокирующий
С Transport Adapter по умолчанию Requests не предоставляет никакого не-блокирующего IO (ввода-вывода). Свойство Response.content
будет блокировать до тех пор, пока весь ответ не загрузится. Если требуется большая детализация, потоковые возможности библиотеки позволяют получать маленькие порции ответа в определенное время. Но и эти вызовы будут блокироваться.
Если не хочется использовать блокировку IO, есть масса проектов, совмещающих Requests с одним из асинхронных фреймворков Python. Например, requests-threads, grequests, requests-futures и requests-async.
Порядок заголовков
В необычных обстоятельствах может понадобится предоставить заголовки в определенном порядке. Если передать OrderedDict
в headers
, это и будет обозначенный порядок. Но порядок заголовков по умолчанию в Requests будет иметь более высокий приоритет, поэтому если их перезаписать в headers
, они могут отображаться беспорядочно в сравнении с теми, что указаны в аргументе.
Чтобы решить эту проблему, необходимо настроить заголовки по умолчанию для объекта Session
, предоставив ему OrderedDict
. Этот порядок и станет приоритетным.
Таймауты
У большинства запросов к внешнем серверам есть прикрепленный таймаут в том случае, если сервер не отвечает вовремя. По умолчанию запросы не прерываются, только если время не указано явно. Без таймаута код может висеть по несколько минут.
connect
— это количество секунд, которые Requests будет выжидать для настройки соединения с вызовом удаленной машины (соответствующей connect()
) в сокете. Хорошей практикой считается настраивать это время чуть больше значения кратного 3, что является стандартным окном ретрансляции пакета TCP.
Когда клиент подключился к серверу и отправил HTTP-запрос, таймаут read
— это количество секунд, которые клиент будет ждать ответа от сервера. (Если точнее, это то количество секунд, которое клиент прождет между отправкой байтов с сервера. В 99,9% случаев оно меньше того времени с момента, когда сервер отправляет первый байт).
Если определить одно значение для таймаута, вот так:
r = requests.get('https://github.com', timeout=5)
Оно будет применено к таймауту connect
и read
. Если нужны отдельные значения, стоит определить их в кортеже:
r = requests.get('https://github.com', timeout=(3.05, 27))
Если сервер очень медленный, можно указать Requests, чтобы он ждал вечно, передав значение None
.
r = requests.get('https://github.com', timeout=None)
Библиотека Requests: HTTP for Humans
Язык Python является универсальным языком программирования. С его помощью можно решать разнообразные задачи в сфере разработки.
Одной из таких сфер, в которой Python занял уверенную позицию, является веб-разработка. Немаловажную роль в этом сыграло обширное комьюнити, различные фреймворки и подключаемые библиотеки, созданные для облегчения жизни программистов. Об одной из таких библиотек сегодня пойдёт речь.
Библиотека Requests: HTTP for Humans
При решении различных задач в сфере веб-разработки, нам часто приходится взаимодействовать с HTTP. Это не самая простая задача для любого языка программирования и Python в этом не исключение. Язык, конечно, содержит встроенные модули, позволяющие отправлять HTTP запросы, но, как это ни парадоксально, их использование едва ли можно отнести к Pythonic-way.
В своё время чтобы обойти монструозность и сложность использования встроенных модулей появилась библиотека Requests. На данный момент она является одной из самых популярных библиотек на github: более 40 000 «звёзд» и используется более, чем в 20 000 open-source проектах. Нередко она используется и в коммерческой разработке.
Для чего и где мы можем применять Requests?
Как было отмечено выше, библиотека позволяет нам легко и с минимальным количеством кода взаимодействовать с веб-приложениями. Это необходимо нам для решения любых задач, связанных с передачей информации от пользователя к серверу и обратно. Но, чтобы что-то хорошо понять, необходимо закрепить теоретические знания практикой, поэтому перейдём от слов к делу.
Примеры использования библиотеки Requests
Для работы с примерами мы будем использовать два способа: работа в командной строке и написание скриптов в .py-файлах для их дальнейшего запуска.
Я показываю использование командной строки, так как это полезный навык, который пригодится в дальнейшем, когда надо будет быстро что-то проверить.
Для начала, поскольку библиотека является внешней, нам необходимо её установить. Делается это очень просто в командной строке:
$ pip install requests
Продолжим использовать консоль. После установки в нашем расположении (у меня это диск D) введем команду:
D:\> python
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
Теперь можем проверить установку библиотеки произведя импорт:
>>> import requests
Получаем ответ от сайта
Первое, что мы сделаем — проверим статус-код ресурса. Иными словами: узнаем, работает ли сайт. Для этого мы создадим простой запрос GET. Подробнее с кодами состояния HTTP можно ознакомиться на сайте Веб-документация MDN.
>>> r = requests.get('http://learn.python.ru')
Проверим, что возвращает нам данный запрос:
>>> r
<Response [200]>
Как мы можем видеть, в качестве ответа мы получили объект класса Response и код 200. Этот код говорит, что ресурс работает и можно с ним взаимодействовать.
А что будет, если мы отправим неправильный запрос?
>>> r = requests.get('http://learn.python.ru/user')
>>> r
<Response [404]>
Как вы можете заметить, этот запрос вернул нам всё тот же объект класса Response, но с другим кодом — 404. Это означает, что страницы ‘/user’ на сайте http://learn.python.ru нет.
Теперь, когда мы познакомились с тем, как отправлять запрос GET с помощью Requests, мы можем продвинуться дальше и сделать что-то более интересное.
Скачаем изображение с сайта
В этом примере мы будем применять всё тот же запрос GET, но, в отличие от предыдущего, мы будем работать с содержимым ответа.
>>> import requests
>>> image = requests.get('https://learn.python.ru/media/projects/sl1_Cj4bKxp.png')
>>> with open('new_image.png', 'wb') as f:
... f.write(image.content)
После выполнения данного скрипта, мы увидим новое изображение под названием new_image.png в директории, из которой у нас запущен скрипт.
Подробнее с классом Response и методами получения его содержимого можно ознакомиться на официальном сайте библиотеки Requests.
Отправим сообщение в WhatsApp
В этом примере, в отличие от примеров выше, мы познакомимся с другим методом — POST. Стоит отметить, что запросы POST и GET являются самыми часто применяемыми при работе с HTTP.
Для реализации этого примера воспользуемся сервисом, предоставляющим API для отправки сообщений. Я буду использовать сервис Chat-Api. Это платный сервис, но у них есть демо-режим, предоставляющий бесплатный доступ на 3 дня, чего нам для реализации этой задачи будет достаточно. После регистрации на сайте и получении Api URL и токена, мы сможем выполнить отправку сообщений в WhatsApp. Вот что нам для этого потребуется:
>>> import requests
>>> url = '<Ваш API URL>/message?token=<Ваш токен>'
>>> data = {"phone": "<номер телефона, начинающийся с 7>", "body": "<текст сообщения>"}
>>> message = requests.post(url, json=data)
И проверим, отправлено ли сообщение:
>>> print(message.text)
Вы должны будете увидеть что-то вроде этого:
{"sent":true,"message":"<номер телефона адресата>@c.us","id":"true_<номер телефона адресата>@c.us_3EB07324DCD36BD13CC4","queueNumber":1}
Загрузим файл на сервер
Для следующего примера воспользуемся сайтом для тестирования HTTP запросов Webhook.site. В качестве URL мы будем использовать ссылку, которая генерируется на сайте автоматически. У вас она будет отличаться от использованной в примере.
>>> import requests
>>> url = 'https://webhook.site/c253969f-1ad8-4888-812e-e57f4eb4924e'
>>> with open('test.txt', 'w') as f:
... f.write('текст для проверки загрузки файла')
>>> with open('test.txt', 'rb') as f:
... r = requests.post(url, {'files': f})
... print(r)
После выполнения скрипта в терминале мы увидим уже знакомый нам объект класса Response и статус код — 200. Это означает, что запрос выполнился. Вернемся снова на сайт Webhook.site, выберем в правой колонке наш запрос и сможем посмотреть содержание выполненного запроса:
Авторизуемся на сайте
В этом примере будем использовать сайт, который нам также потребуется в следующем примере. Для начала зарегистрируемся на сайте WorldWeatherOnline. После удачной регистрации на сайте в личном кабинете вы увидите API KEY, который потребуется для следующего примера.
Для авторизации на сайте нам необходимо в запросе отправить пользовательские данные на сайт. Помимо логина и пароля, мы должны отправить сайту ключи, которые содержатся в заголовках пакета. Чтобы узнать эти ключи нужно выйти из нашей учётной записи, перейти на страницу входа, затем открыть в браузере Developer tools (F12), перейти на вкладку Network и снова авторизоваться. После того как страница загрузится в Developer tools во вкладке Network пролистайте вверх и найдите строчку login.aspx.
Как мы можем заметить во вкладке Headers, при входе мы осуществили запрос POST для передачи данных серверу. Пролистав вниз до блока Form Data, мы найдём все ключи, которые нам необходимо отправить сайту для авторизации.
>>> import requests
>>> url = 'https://www.worldweatheronline.com/developer/login.aspx'
>>> data = {<заносим сюда все ключи, которые необходимо отправить серверу в формате “key”: “value” и не забываем ставить запятые после каждого “value”>}
>>> s = requests.Session()
>>> s = requests.post(url, data=data)
Для проверки выполнения авторизации выведем содержание ответа сервера:
>>> print(s.text)
После выполнения данной функции в консоли мы увидим содержимое страницы в виде текста, то есть так, как страницу “видит” наш браузер — в формате html. Подтверждением успешной авторизации служат следующие строки:
<li><a href="/developer/my/">My Account</a></li>
<li><a href="/developer/logout.aspx">Logout</a></li>
Неавторизованному пользователю данные кнопки недоступны.
Узнаем погоду в Москве
В этом примере мы будем использовать API KEY с сайта WorldWeatherOnline, на котором мы зарегистрировались в прошлом примере. В разделе документации на сайте WorldWeatherOnline приведено подробное описание параметров.
Теперь уже с использованием вашей любимой IDE напишем скрипт, который будет принимать в качестве аргумента из командной строки город, а возвращать значение температуры.
Создадим файл и назовём его weather.py. Запишем в него:
import sys
import requests
def get_weather():
url = 'http://api.worldweatheronline.com/premium/v1/weather.ashx'
city = sys.argv[1]
params = { 'key': '<копируем сюда ключ, полученный на сайте>',
'q': city,
'format': 'json',
'num_of_days': 1,
'lang': 'ru'}
r = requests.get(url, params=params)
the_weather = r.json()
# данной строкой мы преобразуем полученное содержимое страницы
# в формат json, который очень похож на тип данных dict() в Python
# и с которым очень удобно работать
if 'data' in the_weather:
if 'current_condition' in the_weather['data']:
try:
return the_weather['data']['current_condition'][0]
except(IndexError, TypeError):
return 'Server Error'
return 'Server Error'
if __name__ == '__main__':
weather = get_weather()
print(f'Погода сейчас {weather["temp_C"]}, ощущается как {weather["FeelsLikeC"]}')
Запустим наш скрипт в командной строке:
$ python weather.py Moscow
В качестве ответа мы должны увидеть:
Погода сейчас 20, ощущается как 20
В этом примере мы не просто получили какую-то информацию от сервера, но и обработали содержимое полученного ответа. В следующем примере мы разберем еще один метод обработки полученного содержимого ответа.
Напишем простой парсер новостей
В качестве источника новостей будем использовать хаб о Python сайта Habr.com. В этом примере, помимо Requests нам также понадобится библиотека BeautifulSoup. С данной библиотеке можно подробно познакомиться на официальной странице документации Beautiful Soup. Устанавливается она также просто, как и Requests:
$ pip install beautifulsoup4
Создадим файл с названием news.py и запишем в него следующее:
import requests
from bs4 import BeautifulSoup
class HabrPythonNews:
def __init__(self):
self.url = 'https://habr.com/ru/hub/python/'
self.html = self.get_html()
def get_html(self):
try:
result = requests.get(self.url)
result.raise_for_status()
return result.text
except(requests.RequestException, ValueError):
print('Server error')
return False
Метод get_html() класса HabrPythonNews с помощью библиотеки Requests отправляет наш запрос GET к сайту Habr.com и возвращает содержимое страницы в виде текста. Иными словами, мы получаем html страницы. Если мы посмотрим на содержимое страницы (ctrl + U в Google Chrome), то обнаружим там различные блоки, в которых содержится информация. Нас интересуют только заголовки новостей и ссылки на них. Чтобы извлечь нужную нам информацию из содержимого страницы, мы воспользуемся библиотекой Beautiful Soup. Нужный нам блок называется:
<h3>
Давайте теперь добавим функцию для работы с этим блоком:
def get_python_news(self):
soup = BeautifulSoup(self.html, 'html.parser')
news_list = soup.findAll('h3', class_='post__title')
return news_list
Метод get_python_news() возвращает нам все элементы страницы, с тегом
<h3>
И добавим завершающий блок нашего класса:
if __name__ == "__main__":
news = HabrPythonNews()
print(news.get_python_news())
Итоговый код должен выглядеть у нас так:
import requests
from bs4 import BeautifulSoup
class HabrPythonNews:
def __init__(self):
self.url = 'https://habr.com/ru/hub/python/'
self.html = self.get_html()
def get_html(self):
try:
result = requests.get(self.url)
result.raise_for_status()
return result.text
except(requests.RequestException, ValueError):
print('Server error')
return False
def get_python_news(self):
soup = BeautifulSoup(self.html, 'html.parser')
news_list = soup.findAll('h3', class_='post__title')
return news_list
if __name__ == "__main__":
news = HabrPythonNews()
print(news.get_python_news())
При выполнении данного скрипта мы получим ссылки и заголовки новостей с первой страницы хаба. Изменяя параметры поиска
news_list = soup.findAll('h3', class_='post__title')
мы можем получать различные значения.
В качестве заключения
Использование библиотеки Requests не ограничивается приведенными выше примерами. Данная библиотека является очень удобным инструментом для взаимодействия с HTTP. Продолжить знакомство с библиотекой можно на официальном сайте Requests.
Автор: Виталий Калинин
Выпускник курсов Learn Python
Модуль Python Urllib | Портал информатики для гиков
Модуль Urllib — это модуль обработки URL для Python. Он используется для получения URL-адресов (унифицированные указатели ресурсов). Он использует функцию urlopen и может извлекать URL-адреса, используя различные протоколы.
Urllib — это пакет, который собирает несколько модулей для работы с URL, такими как:
- urllib.request для открытия и чтения.
- urllib.parse для разбора URL
- urllib.error для возникших исключений
- urllib.robotparser для разбора файлов robot.txt
Если urllib отсутствует в вашей среде, выполните приведенный ниже код для его установки.
pip install urllib
Давайте посмотрим на это в деталях.
urllib.request
Этот модуль помогает определить функции и классы для открытия URL-адресов (в основном HTTP). Один из самых простых способов открыть такие URL-адреса:
urllib.request.urlopen (URL)
Мы можем видеть это на примере:
The source code of the URL i.e. Geeksforgeeks.
urllib.parse
Этот модуль помогает определять функции для манипулирования URL-адресами и их компонентами, для их построения или разрыва. Обычно он фокусируется на разбиении URL на небольшие компоненты; или объединение различных компонентов URL в строку URL.
Мы можем видеть это из приведенного ниже кода:
|
ParseResult(scheme='https', netloc='www.geeksforgeeks.org', path='/python-langtons-ant/', params='', query='', fragment='') https://www.geeksforgeeks.org/python-langtons-ant/amp/
Примечание. — Различные компоненты URL-адреса разделены и снова объединены. Попробуйте использовать другой URL для лучшего понимания.
Другие функции urllib.parse:
Function | Use |
---|---|
urllib.parse.urlparse | Separates different components of URL |
urllib.parse.urlunparse | Join different components of URL |
urllib.parse.urlsplit | It is similar to urlparse() but doesn’t split the params |
urllib.parse.urlunsplit | Combines the tuple element returned by urlsplit() to form URL |
urllib.parse.urldeflag | If URL contains fragment, then it returns a URL removing the fragment. |
urllib.error
Этот модуль определяет классы для исключения, вызванные urllib.request. Всякий раз, когда возникает ошибка при получении URL, этот модуль помогает в создании исключений. Ниже приведены исключения:
- URLError — Он вызывается для ошибок в URL-адресах или ошибок при получении URL-адреса из-за возможности подключения и имеет свойство ‘reason’, которое сообщает пользователю причину ошибки.
- HTTPError — возникает для экзотических ошибок HTTP, таких как ошибки запроса аутентификации. Это подкласс или URLError. Типичные ошибки: «404» (страница не найдена), «403» (запрос запрещен),
и «401» (требуется аутентификация).
Мы можем видеть это в следующих примерах:
|
URL Error: urlopen error [Errno 11001] getaddrinfo failed
|
HTTP Error 403: Forbidden
urllib.robotparser
Этот модуль содержит единственный класс, RobotFileParser. Этот класс отвечает на вопрос о том, может ли конкретный пользователь получить URL, который опубликовал файлы robot.txt. Robots.txt — это текстовый файл, созданный веб-мастерами, чтобы научить веб-роботов сканировать страницы на их веб-сайте. Файл robot.txt сообщает веб-редактору о том, какие части сервера не должны быть доступны.
Например :
None None True False
Рекомендуемые посты:
Модуль Python Urllib
0.00 (0%) 0 votes
Парсинг url при помощи библиотеки urllib.parse Python
Дошли руки до парсинга. Я не буду пока показывать вам сложные примеры. Пока сделаем парсинг простого урла средствами urllib.parse. Прикол в том, что многие опытные и не опытные программисты собирают урл примерно так: ‘yousite.ru/?’ + ‘param1=’ + str(num1) + ‘&’ + ‘param2=’ + str(num2). Хорошо если у вас мало параметров. Но если их будет много? Что тогда? Ваша задача быстро научиться: разбирать строку, менять параметры, собирать новый урл с изменёнными параметрами.
#!/usr/bin/python3
#freelance.py
import urllib.parse as urllib
if __name__=='__main__':
'''
если вызывается напрямую ./freelance.py, то запускаем скрипт
'''
# разбираем url + получаем параметры
url = 'https://freelance.ru/projects/?cat=4&spec=446'
base_url = url.split('/?')[0]
data = url.split('/?')[-1]
data = urllib.urlparse(url)
print(base_url)
#вывод: https://freelance.ru/projects
query_data = urllib.parse_qs(data.query)
print(query_data)
#вывод: {'cat': ['4'], 'spec': ['446']}
#меняю параметр
query_data['cat'][0]=str(5)
'''
собираем url с изменёнными параметрами
внимание! в urllib.urlunsplit(5 элементов!!!)
'''
new_url = urllib.urlunsplit(('https', 'freelance.ru', '/projects/',\
'cat='+query_data['cat'][0] + '&spec='+query_data['spec'][0], ''))
print(new_url)
'''
вывод:
https://freelance.ru/projects/?cat=5&spec=446
'''
# верхний способ довольно длинный, оптимизируем сборку get-параметров
new_url = base_url + '/?' + urllib.urlencode(query_data, doseq=True)
print(new_url)
'''
вывод:
https://freelance.ru/projects/?spec=446&cat=5
'''
Функция urllib.urlunsplit имеет одну особенность. Вы должны передавать только пять параметров. Если у вас нет 5 параметров, то ставьте пустоту в качестве значения. Обратите внимание на функцию urllib.urlencode. Она собирает get-параметры (ключ=значение) в одну строку. Сколько бы не было параметров, все они будут обработаны.
Если вам нужно собрать url из частей с разделителем /, то воспользуйтесь функцией join
base_url = 'https://freelance.ru'
new_url = '/'.join([base_url, 'param1', 'param2', 'param3'])
print(new_url)
#вывод: https://freelance.ru/projects/param1/param2/param3
Вы можете подробно прочитать про функции библиотеки urllib.parse на страницах: urllib.parse(docs.python.org) и urllib.parse(ilnurgi1.ru)
просмотры: 7386,
уровень: средний уровень,
рейтинг: 5,
дата: 2018-03-30 18:12:02
Комментарии:
urllib.request — Расширяемая библиотека для открытия URL-адресов — документация Python 3.9.0
Откройте URL-адрес url , который может быть либо строкой, либо
Запрос объекта
.
данные должен быть объектом, определяющим дополнительные данные, которые нужно отправить на
server или None
, если такие данные не нужны. См. Запрос
для подробностей.
Модуль
urllib.request использует HTTP / 1.1 и включает Соединение: закрыть заголовок
в своих HTTP-запросах.
Дополнительный параметр timeout указывает время ожидания в секундах для
блокирующие операции, такие как попытка подключения (если не указано,
будет использоваться глобальная настройка тайм-аута по умолчанию). Это на самом деле
работает только для соединений HTTP, HTTPS и FTP.
Если указан контекст , это должен быть экземпляр ssl.SSLContext
описание различных опций SSL. См. Соединение HTTPS
Больше подробностей.
Необязательные параметры cafile и capath определяют набор доверенных
Сертификаты ЦС для запросов HTTPS. cafile должен указывать на один
файл, содержащий набор сертификатов CA, тогда как capath должен
укажите на каталог с хешированными файлами сертификатов. Больше информации можно
можно найти в ssl.SSLContext.load_verify_locations ()
.
Параметр cadefault игнорируется.
Эта функция всегда возвращает объект, который может работать как
диспетчер контекста и имеет свойства url , заголовков и статус .См. urllib.response.addinfourl
для получения более подробной информации об этих свойствах.
Для URL-адресов HTTP и HTTPS эта функция возвращает
http.client.HTTPResponse
слегка изменен объект. К тому же
для трех новых методов, указанных выше, атрибут msg содержит
та же информация, что и причина
атрибут — фраза причины, возвращаемая сервером — вместо
заголовки ответов, как указано в документации для
HTTP-ответ
.
Для FTP, файлов и URL-адресов данных и запросов, явно обрабатываемых устаревшей версией
Классы URLopener
и FancyURLopener
, эта функция
возвращает urllib .response.addinfourl
объект.
Вызывает URLError
при ошибках протокола.
Обратите внимание, что None
может быть возвращено, если никакой обработчик не обрабатывает запрос (хотя
установленный по умолчанию глобальный OpenerDirector
использует
UnknownHandler
, чтобы этого никогда не происходило).
Кроме того, если обнаружены настройки прокси (например, когда * _proxy
установлена переменная окружения, например http_proxy
),
ProxyHandler
установлен по умолчанию и проверяет,
обрабатывается через прокси.
Устаревшая функция urllib.urlopen
из Python 2.6 и ранее была
снято с производства; urllib.request.urlopen ()
соответствует старому
urllib2.urlopen
. Обработка прокси, которая была выполнена путем передачи словаря
параметр urllib.urlopen
, можно получить, используя
ProxyHandler
объектов.
Открывалка по умолчанию вызывает событие аудита
urllib.Request
с аргументами fullurl
, data
, заголовки
,
Метод
взят из объекта запроса.
Изменено в версии 3.2: добавлены cafile и capath .
Изменено в версии 3.2: виртуальные хосты HTTPS теперь поддерживаются, если это возможно (то есть, если
ssl.HAS_SNI
верно).
Новое в версии 3.2: данных может быть повторяющимся объектом.
Изменено в версии 3.3: добавлен cadefault .
Изменено в версии 3.4.3: добавлен контекст .
.
urllib.parse — Разбор URL-адресов на компоненты — документация Python 3.9.0
Исходный код: Lib / urllib / parse.py
Этот модуль определяет стандартный интерфейс для взлома Uniform Resource Locator (URL)
строки в компонентах (схема адресации, сетевое расположение, путь и т. д.), чтобы
объединить компоненты обратно в строку URL и преобразовать «относительный URL»
на абсолютный URL, заданный «базовым URL».
Модуль был разработан в соответствии с RFC в Интернете по Relative Uniform.
Локаторы ресурсов.Он поддерживает следующие схемы URL: файл
, ftp
,
gopher
, hdl
, http
, https
, imap
, mailto
, мм
,
новости
, nntp
, prospero
, rsync
, rtsp
, rtspu
, sftp
,
shttp
, sip
, sips
, snews
, svn
, svn + ssh
, telnet
,
wais
, ws
, wss
.
Модуль urllib.parse
определяет функции, которые делятся на два основных
категории: парсинг URL и цитирование URL. Они подробно описаны в
следующие разделы.
Разбор URL
Функции синтаксического анализа URL-адресов сосредоточены на разделении строки URL-адреса на ее компоненты,
или при объединении компонентов URL в строку URL.
-
urllib.parse.
urlparse
( urlstring , scheme = » , allow_fragments = True ) Разбирает URL-адрес на шесть компонентов, возвращая именованный кортеж из 6 элементов.Эта
соответствует общей структуре URL:
Схема: // netloc / путь; параметры? Запрос # фрагмент
.
Каждый элемент кортежа представляет собой строку, возможно, пустую. Компоненты не разбиты
на более мелкие части (например, сетевое местоположение представляет собой одну строку), а%
побеги не расширяются. Указанные выше разделители не являются частью
результат, за исключением ведущей косой черты в компоненте пути , который сохраняется, если
настоящее время. Например:>>> из urllib.анализировать импорт URL >>> o = urlparse ('http://www.cwi.nl:80/%7Eguido/Python.html') >>> о ParseResult (scheme = 'http', netloc = 'www.cwi.nl: 80', path = '/% 7Eguido / Python.html', params = '', query = '', фрагмент = '') >>> o.scheme 'http' >>> o.port 80 >>> o.geturl () 'http://www.cwi.nl:80/%7Eguido/Python.html'
Следуя спецификациям синтаксиса в RFC 1808 , urlparse распознает
netloc, только если он правильно введен с помощью «//».В противном случае
Предполагается, что ввод является относительным URL-адресом и поэтому начинается с
компонент пути.>>> из urllib.parse import urlparse >>> urlparse ('// www.cwi.nl:80/%7Eguido/Python.html') ParseResult (scheme = '', netloc = 'www.cwi.nl: 80', path = '/% 7Eguido / Python.html', params = '', query = '', фрагмент = '') >>> urlparse ('www.cwi.nl/%7Eguido/Python.html') ParseResult (scheme = '', netloc = '', path = 'www.cwi.nl /% 7Eguido / Python.html', params = '', query = '', фрагмент = '') >>> urlparse ('справка / Python.html ') ParseResult (scheme = '', netloc = '', path = 'help / Python.html', params = '', запрос = '', фрагмент = '')
Схема Аргумент дает схему адресации по умолчанию, которая
используется, только если URL-адрес не указан. Он должен быть одного типа
(текст или байты) как urlstring , за исключением того, что значение по умолчанию''
равно
всегда разрешено, и при необходимости автоматически преобразуется вb ''
.Если аргумент allow_fragments равен false, идентификаторы фрагментов не
признал.Вместо этого они анализируются как часть пути, параметры
или компонент запроса, а фрагмент
возвращаемое значение.Возвращаемое значение — именованный кортеж, что означает, что его элементы могут
можно получить доступ по индексу или как именованные атрибуты, а именно:Атрибут
Индекс
Значение
Значение, если отсутствует
схема
0
Спецификатор схемы URL
схема параметр
netloc
1
Часть сетевого расположения
пустая строка
путь
2
Иерархический путь
пустая строка
параметры
3
Параметры последнего пути
элементпустая строка
запрос
4
Компонент запроса
пустая строка
фрагмент
5
Идентификатор фрагмента
пустая строка
имя пользователя
Имя пользователя
Нет
пароль
Пароль
Нет
имя хоста
Имя хоста (нижний регистр)
Нет
порт
Номер порта как целое число,
при наличииНет
Чтение атрибута
порта
вызоветValueError
, если
в URL-адресе указан неверный порт.См. Раздел
Структурированные результаты синтаксического анализа для получения дополнительной информации об объекте результата.Несовпадающие квадратные скобки в атрибуте
netloc
вызовут
ValueError
.символов в атрибуте
netloc
, которые разлагаются под NFKC
нормализация (используемая в кодировке IDNA) в любой из/
,?
, г.
№
,
.
21,6. urllib.request — Расширяемая библиотека для открытия URL-адресов — документация Python 3.3.7
Откройте URL-адрес url , который может быть строкой или
Объект запроса.
данные должен быть байтовым объектом, определяющим дополнительные данные, которые должны быть отправлены на
server или None, если такие данные не нужны. data также может быть
итерируемый объект, и в этом случае значение Content-Length должно быть указано в
заголовки. В настоящее время HTTP-запросы — единственные, которые используют данных ; в
HTTP-запрос будет POST вместо GET, если параметр data равен
при условии.
данных должен быть буфером в стандартном
application / x-www-form-urlencoded в формате . В
urllib.parse.urlencode () функция принимает отображение или последовательность
2 кортежа и возвращает строку в этом формате. Он должен быть закодирован в байтах
перед использованием в качестве параметра данных . Параметр charset в
Заголовок Content-Type может использоваться для указания кодировки. Если кодировка
не отправляется с заголовком Content-Type, сервер, следующий за
HTTP 1.1 рекомендация может предполагать, что данные закодированы в ISO-8859-1
кодирование. Желательно использовать параметр charset с кодировкой, используемой в
Заголовок Content-Type с запросом.
Модуль
urllib.request использует HTTP / 1.1 и включает заголовок Connection: close
в своих HTTP-запросах.
Дополнительный параметр timeout указывает время ожидания в секундах для
блокирующие операции, такие как попытка подключения (если не указано,
будет использоваться глобальная настройка тайм-аута по умолчанию). Это на самом деле
работает только для соединений HTTP, HTTPS и FTP.
Необязательные параметры cafile и capath определяют набор доверенных
Сертификаты ЦС для запросов HTTPS. cafile должен указывать на один
файл, содержащий набор сертификатов CA, тогда как capath должен
укажите на каталог с хешированными файлами сертификатов. Больше информации можно
можно найти в ssl.SSLContext.load_verify_locations ().
Параметр cadefault указывает, следует ли вернуться к загрузке
хранилище сертификатов по умолчанию, определенное базовой библиотекой OpenSSL, если
Параметры cafile и capath опускаются.Это будет работать только на
некоторые платформы, отличные от Windows.
Предупреждение
Если не указано ни cafile , ни capath , а cadefault — False,
запрос HTTPS не будет проверять сервер
сертификат.
Для URL-адресов http и https эта функция возвращает
http.client.HTTPResponse объект, который имеет следующие
HTTPResponse Objects методов.
Для URL-адресов ftp, файлов и данных, а также для явных запросов, обрабатываемых устаревшей версией
URLopener и FancyURLopener, эта функция
возвращает urllib.response.addinfourl объект, который может работать как
диспетчер контекста и имеет такие методы, как
- geturl () — вернуть URL-адрес полученного ресурса,
обычно используется, чтобы определить, было ли выполнено перенаправление - info () — возвращает метаинформацию страницы, такую как заголовки,
в виде экземпляра email.message_from_string () (см.
Краткий справочник по заголовкам HTTP) - getcode () — вернуть код статуса HTTP ответа.
Вызывает ошибку URLError.
Обратите внимание, что None может быть возвращено, если никакой обработчик не обрабатывает запрос (хотя
установленный по умолчанию глобальный OpenerDirector использует
UnknownHandler, чтобы этого никогда не произошло).
Кроме того, если обнаружены настройки прокси (например, когда * _proxy
установлена переменная окружения, например http_proxy),
ProxyHandler установлен по умолчанию и гарантирует, что запросы
обрабатывается через прокси.
Устаревшая функция urllib.urlopen из Python 2.6 и ранее была
снято с производства; urllib.request.urlopen () соответствует старому
urllib2.urlopen. Обработка прокси, которая была выполнена путем передачи словаря
параметр urllib.urlopen, можно получить, используя
Объекты ProxyHandler.
Изменено в версии 3.2: добавлены cafile и capath .
Изменено в версии 3.2: виртуальные хосты HTTPS теперь поддерживаются, если это возможно (то есть, если
ssl.HAS_SNI верно).
Новое в версии 3.2: данных может быть повторяющимся объектом.
Изменено в версии 3.3: cadefault был добавлен.
.
открытие URL-адреса с urllib в python 3
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…
.