Модуль http.client, с которым мы только что познакомились, предоставляет клиентам HTTP механизмы низкого уровня. Однако при работе с объектами, находящимися в Сети, часто оказывается проще организовать загрузку файлов с помощью стандартного модуля Python urllib.re- quest, который был представлен в разделе этой главы, посвященном FTP. Так как этот модуль обеспечивает еще одну возможность обмена данными по протоколу HTTP, остановимся здесь на его интерфейсах.
Вспомните, что при наличии адреса URL модуль urllib.request либо загружает запрашиваемый объект из Сети в локальный файл, либо создает объект файла, который позволяет осуществлять чтение его содержимого. Благодаря этому сценарий в примере 13.30 выполняет ту же работу, что и сценарий с использованием http.client, который мы только что написали, но он при этом значительно короче.
Пример 13.30. PP4E\Internet\Other\http-getfile-urllib1.py
получает файл с сервера HTTP (web) через сокеты с помощью модуля urllib; urllib поддерживает протоколы HTTP, FTP, HTTPS и обычные файлы в строках адресов URL; для HTTP в строке URL можно указать имя файла или удаленного сценария CGI; смотрите также пример использования urllib в разделе FTP и вызов сценария CGI в последующей главе; Python позволяет получать файлы из сети самыми разными способами, различающимися сложностью и требованиями к серверам: через сокеты, FTP, HTTP, urllib и вывод CGI;
предостережение: имена файлов следует обрабатывать функцией urllib.parse.quote, чтобы экранировать специальные символы, если это не делается в программном коде, — смотрите следующие главы;
import sys
from urllib.request import urlopen
showlines = 6
try:
servername, filename = sys.argv[1:] # аргументы командной строки? except:
servername, filename = ‘learning-python.com’, ‘/index.html’
remoteaddr = ‘http://%s%s’ % (servername, filename) # может быть именем
# CGI—сценария print(remoteaddr)
remotefile = urlopen(remoteaddr) # объект файла для ввода
remotedata = remotefile.readlines() # чтение данных напрямую
remotefile.close()
for line in remotedata[:showlines]: print(line) # строка bytes
# со встроенными символами \n
Почти все тонкости пересылки по HTTP скрыты здесь за интерфейсом urllib.request. Данная версия работает примерно так же, как версия с http.client, которую мы написали выше, но должна сконструировать и передать адрес URL (созданный URL представлен в первой строке вывода сценария). Как отмечалось в разделе этой главы об FTP, функция urlopen из модуля urllib.request возвращает объект, похожий на файл, из которого можно читать данные, находящиеся на сервере. Но поскольку созданный здесь адрес URL начинается с «http://», модуль urllib. request автоматически применяет для загрузки запрашиваемого файла низкоуровневые интерфейсы HTTP, а не FTP:
C:\…\PP4E\Internet\Other> http-getfile-urllib1.py http://learning-python.com/index.html b'<HTML>\n’ b’ \n’ b'<HEAD>\n’
b"<TITLE>Mark Lutz’s Python Training Services</TITLE>\n"
b'<!—mstheme—><link rel="stylesheet" type="text/css" href="_themes/blends/ blen…’
b'</HEAD>\n’
C:\…\PP4E\Internet\Other> http-getfile-urllib1.py www.python.org /index http://www.python.org/index
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// www.w3 ‘
b’\n’ b’\n’
b'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n’ b’\n’
b'<head>\n’
C:\…\PP4E\Internet\Other> http-getfile-urllib1.py www.rmi.net /~lutz http://www.rmi.net/~lutz b'<HTML>\n’ b’\n’ b'<HEAD>\n’
b"<TITLE>Mark Lutz’s Book Support Site</TITLE>\n"
b'</HEAD>\n’
b'<BODY BGCOLOR="#f1f1ff">\n’
C:\…\PP4E\Internet\Other> http-getfile-urllib1.py
localhost /cgi-bin/languages.py?language=Java
http://localhost/cgi-bin/languages.py?language=Java b'<TITLE>Languages</TITLE>\n’ b'<H1>Syntax</H1><HR>\n’
b'<H3>Java</H3><P><PRE>\n’
b’ System.out.println("Hello World"); \n’ b'</PRE></P><BR>\n’
b‘<HR>\n‘
Как и раньше, аргумент с именем файла может содержать не только имя простого файла, но и имя вызываемой программы с дополнительными параметрами. Если внимательно изучить этот вывод, можно заметить, что сценарий работает, даже если опустить «index.html» в конце пути к каталогу на сайте (в третьей команде). В отличие от версии, реализованной на основе использования протокола чистого HTTP, интерфейс на основе URL достаточно сообразителен, чтобы сделать именно то, что требуется.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011