В Python 2 модули веб-клиентов и веб-серверов были слегка разбросаны. Одна из целей Python 3 заключается в том, чтобы разместить эти модули в двух
• http управляет всеми деталями клиент-серверного взаимодействия HTTP:
• client выполняет всю работу на стороне клиента;
• server помогает вам написать веб-сервер;
• cookies и cookiejar управляют cookies, которые сохраняют данные между посещениями;
• urllib работает на базе http:
• request обрабатывает клиентские запросы;
• response обрабатывает ответы сервера;
• parse разбивает URL на части.
Воспользуемся стандартной библиотекой, чтобы получить что-нибудь с сайта. URL в следующем примере возвращает случайную текстовую цитату — это что-то вроде печенья с предсказанием:
>>> import urllib.request as ur
>>> url = 'http://www.iheartquotes.com/api/v1/random'
>>> conn = ur.urlopen(url)
>>> print(conn)
<http.client.HTTPResponse object at 0x1006fad50>
Из официальной документации (http://bit.ly/httpresponse-docs) мы можем узнать, что conn является объектом класса HTTPResponse, содержащим несколько методов, и его метод read() предоставит нам информацию о веб-странице:
>>> data = conn.read()
>>> print(data)
b'You will be surprised by a loud noise.\r\n\n[codehappy]
http://iheartquotes.com/fortune/show/20447\n'
Этот небольшой фрагмент кода открыл соединение TCP/IP с удаленным сервером цитат, создал запрос HTTP и получил HTTP-ответ. Ответ содержит не только данные о странице (цитату). Одна из наиболее важных частей ответа — это
>>> print(conn.status)
200
Значение 200 означает, что все прошло гладко. Существуют десятки кодов статуса HTTP, объединенных в пять диапазонов в соответствии с их первой цифрой (сотни):
• 1xx
• 2xx
• 3xx
• 4xx
• 5xx
Веб-серверы могут отправлять данные назад в том формате, который им нравится. Обычно это HTML (а также немного CSS и JavaScript), но в нашем примере с печеньем с предсказанием это простой текст. Формат данных указывается значением
>>> print(conn.getheader('Content-Type'))
text/plain
Строка text/plain является
Из любопытства взглянем, какие еще заголовки HTTP были нам отправлены:
>>> for key, value in conn.getheaders():
…·····print(key, value)
…
Server nginx
Date Sat, 24 Aug 2013 22:48:39 GMT
Content-Type text/plain
Transfer-Encoding chunked
Connection close
Etag "8477e32e6d053fcfdd6750f0c9c306d6"
X-Ua-Compatible IE=Edge,chrome=1
X-Runtime 0.076496
Cache-Control max-age=0, private, must-revalidate
Помните тот пример работы с telnet, который я показывал ранее? Теперь наша библиотека Python может разбирать заголовки этих HTTP-запросов и размещать их в словарь. Date и Server кажутся довольно очевидными, некоторые другие — нет. Полезно знать, что HTTP имеет набор стандартных заголовков вроде Content-Type и множество опциональных.
За пределами стандартной библиотеки: requests
В начале главы 1 вы увидели программу, которая получает доступ к YouTube API с помощью стандартных библиотек urllib.request и json. После него был другой пример, который использовал стороннюю библиотеку requests. Он был короче и проще для понимания.