- Начинаем работать с requests
- Content
- Disable ssl certificate verification
- Manual ssl verification
- Python – проверка ssl-сертификатов с python –
- Python requests throwing sslerror
- Tutorial & usage¶
- Аутентификация
- Заголовки
- Инспектируем отправленный запрос
- Использование механизма сессий (session)
- Код состояния запроса (status codes)
- Количество повторов запроса
- Объект сессии session
- Ответ (response)
- Параметры строки запроса (query string parameters)
- Производительность
- Тайм-ауты timeouts
- Заключение
Начинаем работать с requests
И так начнем с установки библиотеки requests. Для этого выполните в терминале консоли следующую команду:
$ pip install requests
Если же вы предпочитаете использовать Pipenv для управления пакетами Python, то можете запустить на исполнение следующую команду:
$ pipenv install requests
Установка библиотеки requests в операционной системе Windows и Linux практически не отличаются. В сети достаточно материалов, в которых описан принцип работы с пакетами Python в обеих системах. Поэтому в этой статье касаться этих вопросов мы далее не будем.
После того, как мы установили requests, мы можем ее использовать в своем приложении. Импорт библиотеки requests в ваш код выглядит следующим образом:
import requests
Content
Ответ на Get-запрос, в теле сообщения часто содержит некую ценную информацию, известную как «полезная нагрузка» («Payload»). Используя атрибуты и методы Response, вы можете просматривать payload в разных форматах.
Чтобы увидеть содержимое ответа в байтах, используйте .content:
Disable ssl certificate verification
Let us try to access a website with an invalid SSL certificate, using Python requests
Output :-
This website doesn’t have SSL setup so it raises this error.To disable certificate verification, at the client side, one can use verify attribute.
Output
Since output response 200 is printed, we can assume that request was successful.
Manual ssl verification
one can also pass the link to the certificate for validation via python requests only.
Python – проверка ssl-сертификатов с python –
Python requests throwing sslerror
This is similar to @rafael-almeida ‘s answer, but I want to point out that as of requests 2.11 , there are not 3 values that verify can take, there are actually 4:
True: validates against requests’s internal trusted CAs.False: bypasses certificate validation completely. (Not recommended)- Path to a CA_BUNDLE file. requests will use this to validate the server’s certificates.
- Path to a directory containing public certificate files. requests will use this to validate the server’s certificates.
The rest of my answer is about #4, how to use a directory containing certificates to validate:
Obtain the public certificates needed and place them in a directory.
Strictly speaking, you probably “should” use an out-of-band method of obtaining the certificates, but you could also just download them using any browser.
If the server uses a certificate chain, be sure to obtain every single certificate in the chain.
According to the requests documentation, the directory containing the certificates must first be processed with the “rehash” utility (openssl rehash).
(This requires openssl 1.1.1 , and not all Windows openssl implementations support rehash. If openssl rehash won’t work for you, you could try running the rehash ruby script at https://github.com/ruby/openssl/blob/master/sample/c_rehash.rb , though I haven’t tried this. )
I had some trouble with getting requests to recognize my certificates, but after I used the openssl x509 -outform PEM command to convert the certs to Base64 .pem format, everything worked perfectly.
You can also just do lazy rehashing:
try:
# As long as the certificates in the certs directory are in the OS's certificate store, `verify=True` is fine.
return requests.get(url, auth=auth, verify=True)
except requests.exceptions.SSLError:
subprocess.run(f"openssl rehash -compat -v my_certs_dir", shell=True, check=True)
return requests.get(url, auth=auth, verify="my_certs_dir")
Tutorial & usage¶
Make a GET request to python.org, using Requests:
Or want to try our async session:
But async is fun when fetching some sites at the same time:
Grab a list of all links on the page, as–is (anchors excluded):
>>> r.html.links{'//docs.python.org/3/tutorial/', '/about/apps/', 'https://github.com/python/pythondotorg/issues', '/accounts/login/', '/dev/peps/', '/about/legal/', '//docs.python.org/3/tutorial/introduction.html#lists', '/download/alternatives', 'http://feedproxy.google.com/~r/PythonInsider/~3/kihd2DW98YY/python-370a4-is-available-for-testing.html', '/download/other/', '/downloads/windows/', 'https://mail.python.org/mailman/listinfo/python-dev', '/doc/av', 'https://devguide.python.org/', '/about/success/#engineering', 'https://wiki.python.org/moin/PythonEventsCalendar#Submitting_an_Event', 'https://www.openstack.org', '/about/gettingstarted/', 'http://feedproxy.google.com/~r/PythonInsider/~3/AMoBel8b8Mc/python-3.html', '/success-stories/industrial-light-magic-runs-python/', 'http://docs.python.org/3/tutorial/introduction.html#using-python-as-a-calculator', '/', 'http://pyfound.blogspot.com/', '/events/python-events/past/', '/downloads/release/python-2714/', 'https://wiki.python.org/moin/PythonBooks', 'http://plus.google.com/ Python', 'https://wiki.python.org/moin/', 'https://status.python.org/', '/community/workshops/', '/community/lists/', 'http://buildbot.net/', '/community/awards', 'http://twitter.com/ThePSF', 'https://docs.python.org/3/license.html', '/psf/donations/', 'http://wiki.python.org/moin/Languages', '/dev/', '/events/python-user-group/', 'https://wiki.qt.io/PySide', '/community/sigs/', 'https://wiki.gnome.org/Projects/PyGObject', 'http://www.ansible.com', 'http://www.saltstack.com', 'http://planetpython.org/', '/events/python-events', '/about/help/', '/events/python-user-group/past/', '/about/success/', '/psf-landing/', '/about/apps', '/about/', 'http://www.wxpython.org/', '/events/python-user-group/665/', 'https://www.python.org/psf/codeofconduct/', '/dev/peps/peps.rss', '/downloads/source/', '/psf/sponsorship/sponsors/', 'http://bottlepy.org', 'http://roundup.sourceforge.net/', 'http://pandas.pydata.org/', 'http://brochure.getpython.info/', 'https://bugs.python.org/', '/community/merchandise/', 'http://tornadoweb.org', '/events/python-user-group/650/', 'http://flask.pocoo.org/', '/downloads/release/python-364/', '/events/python-user-group/660/', '/events/python-user-group/638/', '/psf/', '/doc/', 'http://blog.python.org', '/events/python-events/604/', '/about/success/#government', 'http://python.org/dev/peps/', 'https://docs.python.org', 'http://feedproxy.google.com/~r/PythonInsider/~3/zVC80sq9s00/python-364-is-now-available.html', '/users/membership/', '/about/success/#arts', 'https://wiki.python.org/moin/Python2orPython3', '/downloads/', '/jobs/', 'http://trac.edgewall.org/', 'http://feedproxy.google.com/~r/PythonInsider/~3/wh73_1A-N7Q/python-355rc1-and-python-348rc1-are-now.html', '/privacy/', 'https://pypi.python.org/', 'http://www.riverbankcomputing.co.uk/software/pyqt/intro', 'http://www.scipy.org', '/community/forums/', '/about/success/#scientific', '/about/success/#software-development', '/shell/', '/accounts/signup/', 'http://www.facebook.com/pythonlang?fref=ts', '/community/', 'https://kivy.org/', '/about/quotes/', 'http://www.web2py.com/', '/community/logos/', '/community/diversity/', '/events/calendars/', 'https://wiki.python.org/moin/BeginnersGuide', '/success-stories/', '/doc/essays/', '/dev/core-mentorship/', 'http://ipython.org', '/events/', '//docs.python.org/3/tutorial/controlflow.html', '/about/success/#education', '/blogs/', '/community/irc/', 'http://pycon.blogspot.com/', '//jobs.python.org', 'http://www.pylonsproject.org/', 'http://www.djangoproject.com/', '/downloads/mac-osx/', '/about/success/#business', 'http://feedproxy.google.com/~r/PythonInsider/~3/x_c9D0S-4C4/python-370b1-is-now-available-for.html', 'http://wiki.python.org/moin/TkInter', 'https://docs.python.org/faq/', '//docs.python.org/3/tutorial/controlflow.html#defining-functions'}Grab a list of all links on the page, in absolute form (anchors excluded):
>>> r.html.absolute_links{'https://github.com/python/pythondotorg/issues', 'https://docs.python.org/3/tutorial/', 'https://www.python.org/about/success/', 'http://feedproxy.google.com/~r/PythonInsider/~3/kihd2DW98YY/python-370a4-is-available-for-testing.html', 'https://www.python.org/dev/peps/', 'https://mail.python.org/mailman/listinfo/python-dev', 'https://www.python.org/doc/', 'https://www.python.org/', 'https://www.python.org/about/', 'https://www.python.org/events/python-events/past/', 'https://devguide.python.org/', 'https://wiki.python.org/moin/PythonEventsCalendar#Submitting_an_Event', 'https://www.openstack.org', 'http://feedproxy.google.com/~r/PythonInsider/~3/AMoBel8b8Mc/python-3.html', 'https://docs.python.org/3/tutorial/introduction.html#lists', 'http://docs.python.org/3/tutorial/introduction.html#using-python-as-a-calculator', 'http://pyfound.blogspot.com/', 'https://wiki.python.org/moin/PythonBooks', 'http://plus.google.com/ Python', 'https://wiki.python.org/moin/', 'https://www.python.org/events/python-events', 'https://status.python.org/', 'https://www.python.org/about/apps', 'https://www.python.org/downloads/release/python-2714/', 'https://www.python.org/psf/donations/', 'http://buildbot.net/', 'http://twitter.com/ThePSF', 'https://docs.python.org/3/license.html', 'http://wiki.python.org/moin/Languages', 'https://docs.python.org/faq/', 'https://jobs.python.org', 'https://www.python.org/about/success/#software-development', 'https://www.python.org/about/success/#education', 'https://www.python.org/community/logos/', 'https://www.python.org/doc/av', 'https://wiki.qt.io/PySide', 'https://www.python.org/events/python-user-group/660/', 'https://wiki.gnome.org/Projects/PyGObject', 'http://www.ansible.com', 'http://www.saltstack.com', 'https://www.python.org/dev/peps/peps.rss', 'http://planetpython.org/', 'https://www.python.org/events/python-user-group/past/', 'https://docs.python.org/3/tutorial/controlflow.html#defining-functions', 'https://www.python.org/community/diversity/', 'https://docs.python.org/3/tutorial/controlflow.html', 'https://www.python.org/community/awards', 'https://www.python.org/events/python-user-group/638/', 'https://www.python.org/about/legal/', 'https://www.python.org/dev/', 'https://www.python.org/download/alternatives', 'https://www.python.org/downloads/', 'https://www.python.org/community/lists/', 'http://www.wxpython.org/', 'https://www.python.org/about/success/#government', 'https://www.python.org/psf/', 'https://www.python.org/psf/codeofconduct/', 'http://bottlepy.org', 'http://roundup.sourceforge.net/', 'http://pandas.pydata.org/', 'http://brochure.getpython.info/', 'https://www.python.org/downloads/source/', 'https://bugs.python.org/', 'https://www.python.org/downloads/mac-osx/', 'https://www.python.org/about/help/', 'http://tornadoweb.org', 'http://flask.pocoo.org/', 'https://www.python.org/users/membership/', 'http://blog.python.org', 'https://www.python.org/privacy/', 'https://www.python.org/about/gettingstarted/', 'http://python.org/dev/peps/', 'https://www.python.org/about/apps/', 'https://docs.python.org', 'https://www.python.org/success-stories/', 'https://www.python.org/community/forums/', 'http://feedproxy.google.com/~r/PythonInsider/~3/zVC80sq9s00/python-364-is-now-available.html', 'https://www.python.org/community/merchandise/', 'https://www.python.org/about/success/#arts', 'https://wiki.python.org/moin/Python2orPython3', 'http://trac.edgewall.org/', 'http://feedproxy.google.com/~r/PythonInsider/~3/wh73_1A-N7Q/python-355rc1-and-python-348rc1-are-now.html', 'https://pypi.python.org/', 'https://www.python.org/events/python-user-group/650/', 'http://www.riverbankcomputing.co.uk/software/pyqt/intro', 'https://www.python.org/about/quotes/', 'https://www.python.org/downloads/windows/', 'https://www.python.org/events/calendars/', 'http://www.scipy.org', 'https://www.python.org/community/workshops/', 'https://www.python.org/blogs/', 'https://www.python.org/accounts/signup/', 'https://www.python.org/events/', 'https://kivy.org/', 'http://www.facebook.com/pythonlang?fref=ts', 'http://www.web2py.com/', 'https://www.python.org/psf/sponsorship/sponsors/', 'https://www.python.org/community/', 'https://www.python.org/download/other/', 'https://www.python.org/psf-landing/', 'https://www.python.org/events/python-user-group/665/', 'https://wiki.python.org/moin/BeginnersGuide', 'https://www.python.org/accounts/login/', 'https://www.python.org/downloads/release/python-364/', 'https://www.python.org/dev/core-mentorship/', 'https://www.python.org/about/success/#business', 'https://www.python.org/community/sigs/', 'https://www.python.org/events/python-user-group/', 'http://ipython.org', 'https://www.python.org/shell/', 'https://www.python.org/community/irc/', 'https://www.python.org/about/success/#engineering', 'http://www.pylonsproject.org/', 'http://pycon.blogspot.com/', 'https://www.python.org/about/success/#scientific', 'https://www.python.org/doc/essays/', 'http://www.djangoproject.com/', 'https://www.python.org/success-stories/industrial-light-magic-runs-python/', 'http://feedproxy.google.com/~r/PythonInsider/~3/x_c9D0S-4C4/python-370b1-is-now-available-for.html', 'http://wiki.python.org/moin/TkInter', 'https://www.python.org/jobs/', 'https://www.python.org/events/python-events/604/'}Select an Element with a CSS Selector (learn more):
Grab an Element’s text contents:
Introspect an Element’s attributes (learn more):
Render out an Element’s HTML:
Crab an Element’s root tag name:
Show the line number that an Element’s root tag located in:
Select an Element list within an Element:
Search for links within an element:
Search for text on the page:
More complex CSS Selector example (copied from Chrome dev tools):
XPath is also supported (learn more):
You can also select only elements containing certain text:
Аутентификация
Как вам уже, вероятно, известно аутентификация по сути помогает удаленному сервису понять, кто вы. Как правило, вы предоставляете серверу свои учетные данные, передавая их через содержимое заголовка авторизации Authorization или любого другого пользовательского заголовка, заранее определенного удаленной службой.
Заголовки
Заголовки ответа могут дать вам полезную информацию, такую как тип ответа и ограничение по времени, в течение которого необходимо кэшировать ответ.Чтобы посмотреть заголовки, укажите .headers:
response.headers.headers возвращает похожий на словарь объект, позволяющий получить доступ к значениям объекта по ключу. Например, чтобы получить тип содержимого ответа, вы можете получить доступ к Content-Type:
response.headers['Content-Type']Используя ключ content-type или Content-Type — вы получите одно и то же значение.
Теперь вы узнали основное о Response. Вы увидели его наиболее используемые атрибуты и методы в действии. Давайте сделаем шаг назад и посмотрим как изменяются ответы при настройке Get-запросов.
Инспектируем отправленный запрос
Когда вы делаете запрос, библиотека requests предварительно готовит запрос, прежде чем отправить его на целевой сервер. Подготовка запроса включает в себя такие вещи, как проверка корректности заголовков и сериализация содержимого в формате JSON.
Вы можете просмотреть содержимое подготовленного к отправке запроса, используя объект типа PreparedRequest, обратившись к свойству объекта Response.request:
Использование механизма сессий (session)
Для организации сессионного взаимодействия вашего приложения с сервером используется объект Session, который позволяет сохранять необходимые настройки для отправки данных от запроса к запросу в течение всей текущей сессии. То есть он сохраняет и задает содержимое файлов cookie во всех запросах, сформированных с использованием текущего экземпляра объекта Session, и гарантирует использование выделенного пула соединений при дальнейшем взаимодействии с сервером. Объект Sesson поддерживает любые методы запросов из состава API requests.
И так давайте сохраним некоторые данные cookie в запросе:
Код состояния запроса (status codes)
Первым битом информации, которую вы можете получить от объекта ответа Response, является код состояния запроса к серверу status codes. Код состояния информирует вас о статусе нашего запроса.
Например, статус 200 OK означает, что ваш запрос был успешным, а статус 404 NOT FOUND означает, что искомый ресурс не найден. Существует много других кодов состояния запроса, которые могут дать вам более детальное представление о том, что же все таки произошло с отправленным запросом.
Используя свойство объекта response.status_code, мы можем получить доступ к коду состояния ответа, который вернул удаленный сервер:
>>> response.status_code 200
При обращении к свойству .status_code мы получили значение 200, что означает, что наш запрос был успешным, и сервер отправил нам данные, которые мы запрашивали.
В большинстве случаев эту информацию мы будем использовать для реализации в своем коде различной логики: управлять дальнейшей работой нашего приложения:
if response.status_code == 200:
print('Success!')
elif response.status_code == 404:
print('Not Found.')В соответствии с логикой этого примера кода, если сервер возвращает код состояния 200, то наша программа напечатает «Success!». Если же — 404, то напечатает “Not Found”.
Библиотека requests существенно упрощает процесс взаимодействия вашего приложения с сервером. Однако необходимо знать ее некоторые довольно специфические особенности. Так например, если мы используем экземпляр объекта Response в условном выражении, то его логическое значение приравнивается к True, если был получен код состояния запроса в диапазоне от 200 до 400, и только в противном случае False.
Поэтому мы можем упростить последний пример, переписав код оператора if следующим образом:
if response:
print('Success!')
else:
print('An error has occurred.')Маленькая техническая деталь: этот тест на истинность значения показал такой результат возможным, так как в объекте Response специальный метод класса __bool__()переопределен.
Это означает то, что поведение по умолчанию объекта Response при вычислении его логического значения было переопределено для процедуры проверки кода состояния запроса.
Имейте в виду, что этот способ проверки не гарантирует, что код состояния вашего запроса успешен и равен 200. Причиной прохождения проверки на истинность является то, что запрос может получать и другие “успешные” коды состояния в диапазоне от 200 до 400.
Такие, например, как 204 NO CONTENT и 304 NOT MODIFIED, которые также можно считать в определенном смысле “успешными”, так как они определяют некоторый успешно обработанный сервером ответ на запрос. Например, код 204 информирует нас, что запрос был успешным, но тело сообщения ответа сервера не ничего не содержит.
Поэтому используете этот способ проверки, если захотите узнать, был ли запрос в целом успешным, а только затем, при необходимости, обработать содержимое ответа соответствующим образом на основе значения его кода состояния.
Количество повторов запроса
В случае если ваш запрос по той или иной причине был неудачен, то вы можете указать приложению повторить тот же запрос заданное число раз. Однако requests не будет это делать для вас по умолчанию. Чтобы использовать эту возможность, необходимо реализовать свой так называемый транспортный адаптер Transport Adapter.
Объект сессии session
До сих пор мы имели дело с сетевыми интерфейсами запросов и API высокого уровня, такими как методы get() и post(). Эти методы абстрагирует пользователя от того, что происходит “под капотом” библиотеки, когда мы отправляем запросы.
Одну из основных ролей при абстрагировании пользователя от деталей работы библиотеки, играет класс Session. Если вы хотите осуществлять непосредственный контроль над выполнением запросов, а так же повысить их производительность, то вам необходимо использовать все возможности экземпляров класса Session.
Как мы уже знаем, сессии используются для сохранения некоторого набора настроек от запроса к запросу при обращении к какое-либо удаленной службе. Например, если вы хотите использовать одни и те же данные аутентификации в течение определенного периода времени для отправки нескольких запросов, то можете использовать сессии следующим образом:
Ответ (response)
Объект Response является мощным средством для просмотра содержимого и обработки результатов наших запросов. Давайте пошлем, рассмотренный нами выше, запрос GET еще раз, но в этот раз сохраним принятое значение с объектом ответа в переменной, и затем поближе познакомиться с его атрибутами (свойствами), а также поведением:
Параметры строки запроса (query string parameters)
Одним из самых распространенных способов настройки запроса GET является передача серверу данных в URLстроки запроса.
Обратите внимание, что GET запрос не имеет тела сообщения. Но, это не означает, что с его помощью мы не можем передать серверу никакую информацию. Это можно делать с помощью специальных GET параметров. Чтобы добавить GET параметры к запросу, нужно в конце URL-адреса поставить знак ? и после него начинать задавать их по следующему правилу: имя_параметра1=значение_параметра1&имя_параметра2=значение_параметра2. Разделителем между параметрами служит знак &.
Для передачи GET параметров запроса необходимо передать нужную информацию в именованный параметр params метода get(). Например, следующим способом вы можете использовать Search API GitHub для более узкого поиска репозитория библиотеки requests:
Производительность
При использовании requests, особенно при работе ваших приложений непосредственно в production environment среде, важно учитывать влияние производительности. Такие возможности приложения, как контроль над времени ожидания ответа сервера, сессиями и ограничение повторных попыток обращения к удаленным службам, помогут обеспечить бесперебойную и устойчивую работу вашего приложения.
Тайм-ауты timeouts
Допустим ваше приложение отправляет запрос к некоторой удаленной службе, далее основной поток выполнения кода будет приостановлен, пока приложение будет дождаться ответа на отправленный запрос, и лишь после его получения продолжит свою работу. Конечно, если ваше приложение будет слишком долго ожидать ответ от сервера, то это может привести к следующим негативным последствиям: незавершенные запросы к удаленным службам могут автоматически сохраняться и накапливаться в памяти, пострадает отзывчивость интерфейса приложения на действия пользователя, а фоновые задания могут просто зависнуть.
Уточнение для тех, кто пока не сталкивался с этой проблемой. При выполнении синхронного кода каждая операция ожидает окончания предыдущей, то есть код выполняется строго последовательно в одном потоке. Поэтому приложение может зависнуть, если какая-то операция выполняется слишком долго.
Асинхронный код убирает блокирующую операцию из основного потока программы в отдельный, так что она продолжает выполняться, но в другой области памяти, а основной поток продолжает выполнение кода приложения.
По умолчанию requests будет ждать ответа на запрос от сервера до бесконечности, поэтому рекомендуется практически во всех случаях указывать интервал ожидания, чтобы избежать всех, перечисленных выше, негативных последствий. Чтобы установить интервал времени ожидания запроса, используйте именованный параметр timeout.
Заключение
И так мы прошли долгий путь в изучении возможностей Python библиотеки requests.
Теперь вы умеете:
