Шаг 243.
Основы языка Python.
Взаимодействие с Интернетом. Обмен данными по протоколу HTTP

    На этом шаге мы рассмотрим особенности отправки данных по этому протоколу.

    Модуль http.client позволяет получить информацию из Интернета по протоколам HTTP и HTTPS. Отправить запрос можно методами GET, POST и HEAD.

    Для создания объекта соединения, использующего протокол HTTP, предназначен класс HTTPConnection. Его конструктор имеет следующий формат:

  HTTPConnection(<Домен>[, <Порт>[, timeout[, source_address]]])

    В первом параметре указывается название домена без протокола. Во втором параметре задается номер порта - если параметр не указан, используется порт 80. Номер порта можно также задать после названия домена через двоеточие. Пример создания объекта соединения:

>>> from http.client import HTTPConnection
>>> con = HTTPConnection("test1.ru")
>>> con2 = HTTPConnection("test1.ru", 80)
>>> con3 = HTTPConnection("test1.ru:80")

    После создания объекта соединения необходимо отправить запрос, возможно, с параметрами, вызвав метод request() класса HTTPConnection. Формат метода:

  request (<Метод>, <Путь>[, body=None][, headers=<Заголовки>])

    В первом параметре указывается метод передачи данных (GET, POST или HEAD). Второй параметр задает путь к запрашиваемому файлу или вызываемой программе, отсчитанный от корня сайта. Если для передачи данных используется метод GET, то после вопросительного знака можно указать передаваемые данные. В необязательном третьем параметре задаются данные, которые передаются методом POST, - допустимо указать строку, файловый объект или последовательность. Четвертый параметр задает в виде словаря HTTP-заголовки, отправляемые на сервер.

    Получить объект результата запроса позволяет метод getresponse(). Он возвращает результат выполненного запроса, представленный в виде объекта класса HTTPResponse. Из него мы сможем получить ответ сервера.

    Прочитать ответ сервера (без заголовков) можно с помощью метода read( [<Количество байт>]) класса HTTPResponse. Если параметр не указан, метод read() возвращает все данные, а при наличии параметра - только указанное количество байтов при каждом вызове. Если данных больше нет, метод возвращает пустую строку. Прежде чем выполнять другой запрос, данные должны быть получены полностью. Метод read() возвращает последовательность байтов, а не строку. Закрыть объект соединения позволяет метод close() класса HTTPConnection. Для примера отправим запрос методом GET и прочитаем результат.

>>> from http.client import HTTPConnection
>>> from urllib.parse import urlencode
>>> data = urlencode({"color": "Красный", "var": 15}, encoding="cp1251")
>>> headers = { "User-Agent": "MySpider/1.0",
"Accept": "text/html, text/plain, application/xml",
"Accept-Language": "ru, ru-RU", 
"Accept-Charset": "windows-1251",
"Referer": "/index.php" }
>>> con = HTTPConnection("mail.ru")
>>> con.request("GET", "/testrobots.php?%s" % data, headers=headers)
>>> result  = con.getresponse() #  Создаем объект результата
>>> print (result.read().decode("cp1251" )) # Читаем данные
<html> <head><title>301 Moved Permanently</title></head> 
<body bgcolor="white"> 
<center><h1>301 Moved Permanently</h1></center> 
<hr><center>nginx/1.14.1</center> 
</body> 
</html>

>>> con.close() # Закрываем объект соединения

    Теперь отправим данные методом POST. В этом случае в первом параметре метода request() задается значение "POST", а данные передаются через третий параметр. Размер строки запроса автоматически указывается в заголовке Content-Length. Пример отправки данных методом POST приведен ниже.

>>> from http.client import HTTPConnection
>>> from urllib.parse import urlencode
>>> data = urlencode({"color": "Красный", "var": 15}, encoding="cp1251")
>>> headers = { "User-Agent": "MySpider/1.0",
"Accept": "text/html, text/plain, application/xml",
"Accept-Language": "ru, ru-RU", 
"Accept-Charset": "windows-1251",
"Content-Type": "application/x-www-form-urlencoded",
"Referer": "/index.php" }
>>> con = HTTPConnection("mail.ru")
>>> con.request("POST", "/testrobots.php?%s" % data, headers=headers)
>>> result  = con.getresponse() #  Создаем объект результата
>>> print (result.read().decode("cp1251" )) # Читаем данные
<html> <head><title>301 Moved Permanently</title></head> 
<body bgcolor="white"> 
<center><h1>301 Moved Permanently</h1></center> 
<hr><center>nginx/1.14.1</center> 
</body> 
</html>

>>> con.close() # Закрываем объект соединения

    Обратите внимание на заголовок Content-Type. Если в нем указано значение application/x-www-form-urlencoded, это означает, что отправлены данные формы. При наличии этого заголовка некоторые программные платформы автоматически производят разбор строки запроса. Например, в РНР переданные данные будут доступны через глобальный массив $_POST. Если же заголовок не указать, то данные через массив $_POST доступны не будут.

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг