Использование cURL в Python с помощью PycURL
В этом руководстве мы узнаем, как использовать PycURL, который является интерфейсом к библиотеке cURL в Python. cURL – это инструмент, используемый для передачи данных на сервер и с сервера, а также для выполнения различных типов запросов данных. PycURL отлично подходит для тестирования REST API, загрузки файлов и т.д.
Некоторые разработчики предпочитают использовать Postman для тестирования API, но PycURL – еще один подходящий вариант, поскольку он поддерживает несколько протоколов, таких как FILE, FTPS, HTTPS, IMAP, POP3, SMTP, SCP, SMB и т.д. Более того, PycURL пригодится, когда много одновременных, быстрых и надежных подключений.
Как упоминалось выше, PycURL – это интерфейс к библиотеке libcURL в Python, поэтому PycURL наследует все возможности libcURL. PycURL чрезвычайно быстр (известно, что он намного быстрее, чем Requests, которая представляет собой библиотеку Python для HTTP-запросов), имеет поддержку нескольких протоколов, а также содержит сокеты для поддержки сетевых операций.
Предварительные условия
Прежде чем продолжить это руководство, обратите внимание, что есть несколько предварительных условий. Вы должны иметь базовое представление о синтаксисе Python или иметь хотя бы начальный опыт программирования на каком-либо другом языке. Кроме того, вы должны хорошо понимать общие сетевые концепции, такие как протоколы и их типы, а также режим связи клиент-сервер. Знакомство с этими концепциями необходимо для понимания библиотеки PycURL.
Установка
Процесс установки PycURL довольно прост и понятен для всех операционных систем. Вам просто нужно установить libcURL в вашей системе, чтобы использовать PycURL.
ОС Mac и Linux
Для Mac OS и Linux установка PycURL является самой простой, так как она не имеет зависимостей, а libcURL устанавливается по умолчанию. Просто запустите следующую команду в своем терминале, и установка будет завершена:
Установка через pip
$ pip install pycurl
Через easy_install
$ easy_install pycurl
ОС Windows
Однако для Windows необходимо установить несколько зависимостей, прежде чем PyCURL можно будет использовать в ваших программах. Если вы используете официальный дистрибутив Python (т.е. вы загрузили версию Python с официального сайта https://www.python.org), а также pip, вам просто нужно запустить следующую команду в командной строке и установка будет произведена:
$ pip install pycurl
Если вы не используете pip, установщики EXE и MSI доступны в PycURL Windows. Вы можете скачать и установить их прямо оттуда, как и любое другое приложение.
Примеры кода
В этом разделе мы рассмотрим некоторые примеры кодирования PycURL, демонстрирующие различные функции интерфейса.
Как упоминалось во введении, PycURL поддерживает множество протоколов и имеет множество сложных функций. Однако в наших примерах мы будем работать с протоколом HTTP для тестирования API-интерфейсов REST, используя наиболее часто используемые методы HTTP: GET, POST, PUT и DELETE, а также несколько других примеров. Мы напишем синтаксис для их объявления в Python 3, а также объясним, что они делают.
Пример 1: отправка HTTP-запроса GET
Простая сетевая операция PycURL – получить информацию с заданного сервера, используя его URL-адрес. Это называется запросом GET, поскольку он используется для получения сетевого ресурса.
Простой запрос GET можно выполнить с помощью PycURL, импортировав модуль BytesIO и создав его объект, который создается для передачи данных и файлов по URL-адресам.
Требуемый URL-адрес устанавливается с помощью функции setopt(), которая используется как setopt (параметр, значение). Параметр option указывает, какую опцию установить, например URL, WRITEDATA и т.д., а параметр value указывает значение, присвоенное этой конкретной опции.
Данные, полученные из заданного URL-адреса, затем записываются в виде байтов в объект BytesIO. Затем байты считываются из объекта BytesIO с помощью функции getvalue() и впоследствии декодируются для печати HTML на консоли.
Вот пример того, как это сделать:
import pycurl
from io import BytesIO
b_obj = BytesIO()
crl = pycurl.Curl()
# Set URL value
crl.setopt(crl.URL, 'https://wiki.python.org/moin/BeginnersGuide')
# Write bytes that are utf-8 encoded
crl.setopt(crl.WRITEDATA, b_obj)
# Perform a file transfer
crl.perform()
# End curl session
crl.close()
# Get the content stored in the BytesIO object (in byte characters)
get_body = b_obj.getvalue()
# Decode the bytes stored in get_body to HTML and print the result
print('Output of GET request:\n%s' % get_body.decode('utf8'))
Вывод:
Output of GET request: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv = "Content-Type" content = "text/html; charset = utf-8"> <meta name="robots" content="index,nofollow"> <title>BeginnersGuide - Python Wiki</title> <script type="text/javascript" src = "/wiki/common/js/common.js" ></script> <script type = "text/javascript" > <!-- var search_hint = "Search"; //--> </script> . . .
Пример 2: изучение заголовков ответа GET
Вы также можете получить заголовки ответов веб-сайта с помощью PycURL. Заголовки ответа можно проверить по нескольким причинам, например, чтобы узнать, какая кодировка была отправлена с ответом и соответствует ли она кодировке, предоставленной сервером.
В нашем примере мы будем изучать заголовки ответов просто для того, чтобы найти различные имена атрибутов и их соответствующие значения.
Чтобы проверить заголовки ответа, нам сначала нужно их извлечь, и мы делаем это с помощью параметра HEADERFUNCTION и отображаем их с помощью нашей самоопределяемой функции (в данном случае display_header()).
Мы предоставляем URL-адрес сайта, заголовки ответов которого мы хотим изучить. HEADERFUNCTION отправляет заголовки ответа в функцию display_header(), где они соответствующим образом отформатированы. Заголовки ответа декодируются в соответствии с указанным стандартом и делятся на соответствующие им имена и значения. Пробелы между именами и значениями удаляются, а затем они переводятся в нижний регистр.
Заголовки ответа затем записываются в объект BytesIO, передаются запрашивающей стороне и, наконец, отображаются в надлежащем формате.
from io import BytesIO
import pycurl
headers = {}
def display_header(header_line):
header_line = header_line.decode('iso-8859-1')
# Ignore all lines without a colon
if ':' not in header_line:
return
# Break the header line into header name and value
h_name, h_value = header_line.split(':', 1)
# Remove whitespace that may be present
h_name = h_name.strip()
h_value = h_value.strip()
h_name = h_name.lower() # Convert header names to lowercase
headers[h_name] = h_value # Header name and value.
def main():
print('**Using PycURL to get Twitter Headers**')
b_obj = BytesIO()
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://twitter.com')
crl.setopt(crl.HEADERFUNCTION, display_header)
crl.setopt(crl.WRITEDATA, b_obj)
crl.perform()
print('Header values:-')
print(headers)
print('-' * 20)
main()
Вывод:
**Using PycURL to get Twitter Headers**
Header values:-
{'cache-control': 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0', 'content-length': '303055', 'content-type': 'text/html;charset=utf-8', 'date': 'Wed, 23 Oct 2019 13:54:11 GMT', 'expires': 'Tue, 31 Mar 1981 05:00:00 GMT', 'last-modified': 'Wed, 23 Oct 2019 13:54:11 GMT', 'pragma': 'no-cache', 'server': 'tsa_a', 'set-cookie': 'ct0=ec07cd52736f70d5f481369c1d762d56; Max-Age=21600; Expires=Wed, 23 Oct 2019 19:54:11 GMT; Path=/; Domain=.twitter.com; Secure', 'status': '200 OK', 'strict-transport-security': 'max-age=631138519', 'x-connection-hash': 'ae7a9e8961269f00e5bde67a209e515f', 'x-content-type-options': 'nosniff', 'x-frame-options': 'DENY', 'x-response-time': '26', 'x-transaction': '00fc9f4a008dc512', 'x-twitter-response-tags': 'BouncerCompliant', 'x-ua-compatible': 'IE=edge,chrome=1', 'x-xss-protection': '0'}
--------------------
В случаях, когда у нас есть несколько заголовков с одним и тем же именем, будет сохранено только последнее значение заголовка. Чтобы сохранить все значения в многозначных заголовках, мы можем использовать следующий фрагмент кода:
if h_name in headers:
if isinstance(headers[h_name], list):
headers[name].append(h_value)
else:
headers[h_name] = [headers[h_name], h_value]
else:
headers[h_name] = h_value
Пример 3: отправка данных формы через HTTP POST
POST-запрос – отправляет данные на веб-сервер, заключая их в тело HTTP-запроса. Когда загружаете файл или отправляете форму, вы в основном отправляете запрос POST на указанный сервер.
Запрос POST может быть выполнен с использованием PycURL, сначала установив URL-адрес для отправки данных формы через функцию setopt. Данные, которые должны быть отправлены, сначала сохраняются в форме словаря (в парах ключ-значение), а затем кодируются в URL-адресе с использованием функции urlencode, найденной в модуле urllib.parse.
Мы используем параметр POSTFIELDS при отправке данных формы, поскольку он автоматически устанавливает метод HTTP-запроса на POST, а также обрабатывает наши данные pf.
from urllib.parse import urlencode
import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
data = {'field': 'value'}
pf = urlencode(data)
# Sets request method to POST,
# Content-Type header to application/x-www-form-urlencoded
# and data to send in request body.
crl.setopt(crl.POSTFIELDS, pf)
crl.perform()
crl.close()
Примечание. Если вы хотите указать другой метод запроса, вы можете использовать для этого параметр CUSTOMREQUEST. Просто напишите название метода запроса по вашему выбору в пустых кавычках после crl.CUSTOMREQUEST.
crl.setopt(crl.CUSTOMREQUEST, '')
Пример 4: загрузка файлов с помощью Multipart POST
Есть несколько способов воспроизвести загрузку файла в HTML-форме с помощью PycURL:
- Если данные, которые должны быть отправлены с помощью запроса POST, находятся в файле в вашей системе, вам необходимо сначала установить URL-адрес, по которому вы хотите отправить данные. Затем вы указываете свой метод запроса, как HTTPPOST и используете опцию fileupload для загрузки содержимого желаемого файла.
import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
crl.setopt(crl.HTTPPOST, [
('fileupload', (
# Upload the contents of the file
crl.FORM_FILE, './my-resume.doc',
)),
])
crl.perform()
crl.close()
Примечание. Если вы хотите изменить имя или тип содержимого файла, вы можете сделать это, внеся небольшие изменения в приведенный выше код:
crl.setopt(crl.HTTPPOST, [
('fileupload', (
# Upload the contents of this file
crl.FORM_FILE, './my-resume.doc',
# Specify a file name of your choice
crl.FORM_FILENAME, 'updated-resume.doc',
# Specify a different content type of upload
crl.FORM_CONTENTTYPE, 'application/msword',
)),
])
- Для файловых данных, которые у вас есть в памяти, все, что зависит от реализации запроса POST, – это FORM_BUFFER и FORM_BUFFERPTR вместо FORM_FILE, поскольку они извлекают данные для отправки непосредственно из памяти.
import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
crl.setopt(crl.HTTPPOST, [
('fileupload', (
crl.FORM_BUFFER, 'contact-info.txt',
crl.FORM_BUFFERPTR, 'You can reach me at [email protected]',
)),
])
crl.perform()
crl.close()
Пример 5: загрузка файла с помощью HTTP PUT
Запрос PUT по своей природе похож на запрос POST, за исключением того факта, что его можно использовать для загрузки файла в теле запроса. Вы используете запрос PUT, когда знаете URL-адрес объекта, который хотите создать или перезаписать. По сути, PUT заменяет все, что в настоящее время существует по целевому URL-адресу, чем-то другим.
Если желаемые данные для загрузки находятся в физическом файле, вам сначала нужно установить целевой URL, затем вы загружаете файл и открываете его. Важно, чтобы файл оставался открытым, пока объект cURL его использует. Затем данные считываются из файла с помощью READDATA.
Наконец, передача файла (загрузка) выполняется с помощью функции выполнения, после чего сеанс cURL завершается. Наконец, файл, который был первоначально открыт для объекта CURL, закрывается.
import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
dat_file = open('data.txt')
crl.setopt(crl.UPLOAD, 1)
crl.setopt(crl.READDATA, dat_file)
crl.perform()
crl.close()
dat_file.close()
Если данные файла расположены в буфере, реализация PycURL практически такая же, как и при загрузке данных, расположенных в физическом файле, с небольшими изменениями. Объект BytesIO кодирует данные, используя указанный стандарт. Это связано с тем, что для READDATA требуется объект, подобный вводу-выводу, а закодированные данные необходимы для Python 3. Эти закодированные данные хранятся в буфере, а затем он считывается. Выполняется загрузка данных, и после завершения загрузки сеанс cURL завершается.
import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
data = '{"person":{"name":"billy","email":"[email protected]"}}'
buffer = BytesIO(data.encode('utf-8'))
crl.setopt(crl.UPLOAD, 1)
crl.setopt(crl.READDATA, buffer)
crl.perform()
crl.close()
Пример 6: отправка HTTP-запроса DELETE
Еще один важный и часто используемый HTTP-метод – это DELETE. Он запрашивает, чтобы сервер удалил ресурс, указанный целевым URL-адресом. Его можно реализовать с помощью функции CUSTOMREQUEST, как показано в примере кода ниже:
import pycurl crl = pycurl.Curl() crl.setopt(crl.URL, "http://api.example.com/user/148951") crl.setopt(crl.CUSTOMREQUEST, "DELETE") crl.perform() crl.close()
Пример 7: запись в файл
PycURL также можно использовать для сохранения ответа в файл. Мы используем функцию open, чтобы открыть файл, и ответ возвращается в виде файлового объекта. Функция open имеет вид: open (файл, режим). Параметр file представляет путь и имя файла, который нужно открыть, а mode представляет режим, в котором вы хотите открыть файл. В нашем примере важно, чтобы файл был открыт в двоичном режиме (т.е. wb), чтобы избежать кодирования и декодирования ответа.
import pycurl
file = open('pycurl.md','wb')
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://wiki.python.org/moin/BeginnersGuide')
crl.setopt(crl.WRITEDATA, file)
crl.perform()
crl.close()
Заключение
В этом руководстве мы узнали об интерфейсе PycURL в Python. Мы начали с обсуждения некоторых общих функций PycURL и его связи с библиотекой libcURL в Python. Затем мы увидели процесс установки PycURL для разных операционных систем.
Наконец, мы рассмотрели некоторые общие примеры PycURL, которые продемонстрировали различные функции, предлагаемые PycURL, такие как методы HTTP GET, POST, PUT и DELETE. После изучения этого руководства вы сможете легко извлекать объекты, идентифицированные по URL-адресу в программе Python.
Автор