FTP является лишь одним из способов передачи информации через Сеть, и в библиотеке Python есть более универсальные средства для выполнения такой загрузки, как в предыдущем сценарии. Пожалуй, наиболее простым в этом отношении является модуль urllib.request: получив строку с адресом в Интернете — адрес URL, или унифицированный указатель ресурса (Uniform Resource Locator) — этот модуль открывает соединение с указанным сервером и возвращает объект, похожий на файл, который можно читать с помощью обычных вызовов методов объекта файла (например, read, readline).
Такой высокоуровневый интерфейс может быть применен для загрузки всего, что имеет адрес в Сети, — файлов, опубликованных на FTP-сайтах (используя адреса URL, начинающиеся с ftp://), веб-страниц и вывода сценариев, расположенных на удаленных серверах (используя адреса URL, начинающиеся с http://), и даже локальных файлов (используя адреса URL, начинающиеся с file://). В частности, сценарий в примере 13.2 делает то же, что и сценарий в примере 13.1, но для получения файла дистрибутива с исходными текстами вместо модуля конкретного протокола ftplib использует более универсальный модуль urllib.re— quest.
Пример 13.2. PP4E\Internet\Ftp\getone-urllib.py
#!/usr/local/bin/python
Сценарий на языке Python для загрузки файла по строке адреса URL;
вместо ftplib использует более высокоуровневый модуль urllib;
urllib поддерживает протоколы FTP, HTTP, HTTPS на стороне клиента, локальные файлы, может работать с прокси-серверами, выполнять инструкции перенаправления, принимать cookies и многое другое; urllib также позволяет загружать страницы html, изображения, текст и так далее;
смотрите также парсеры Python разметки html/xml веб-страниц, получаемых с помощью urllib, в главе 19;
import os, getpass
from urllib.request import urlopen # веб—инструменты на основе сокетов
filename = ‘monkeys.jpg‘ # имя удаленного/локального файла
password = getpass.getpass(‘Pswd?’)
remoteaddr = ‘ftp://lutz:%s@ftp.rmi.net/%s;type=i’ % (password, filename) print(‘Downloading’, remoteaddr)
# такой способ тоже работает:
# urllib.request.urlretrieve(remoteaddr, filename)
remotefile = urlopen(remoteaddr) # возвращает объект типа файла для ввода localfile = open(filename, ‘wb’) # локальный файл для сохранения данных
localfile.write(remotefile.read()) localfile.close() remotefile.close()
Обратите внимание, что здесь выходной файл снова открывается в двоичном режиме — данные, получаемые модулем urllib, возвращаются в виде строк байтов, даже веб-страницы HTTP. Не ломайте голову над устройством строки URL, использованной здесь, — она, безусловно, сложна, но мы подробно будем рассматривать структуру адресов URL в целом в главе 15. Мы также вновь будем обращаться к urllib в этой и последующих главах для получения веб-страниц, форматирования сгенерированных строк URL и получения вывода удаленных сценариев в Сети.
С технической точки зрения urllib.request поддерживает целый ряд протоколов Интернета (HTTP, FTP и локальные файлы). В отличие от ftplib, модуль urllib.request используется в целом для чтения удаленных объектов, но не для записи или выгрузки их на сервер (хотя протоколы HTTP и FTP поддерживают такую возможность). Как и при использовании ftplib, получение данных обычно должно осуществляться в отдельных потоках выполнения, если блокировка составляет предмет для беспокойства. Однако базовый интерфейс, показанный в этом сценарии, прост. Вызов:
remotefile = urllib.request.urlopen(remoteaddr) # возвращает объект
# типа файла для ввода
соединяется с сервером, указанным в строке URL remoteaddr, и возвращает объект типа файла, подключенный к потоку загрузки (здесь — сокет FTP). Вызов метода read извлекает содержимое файла, которое записывается в локальный файл на стороне клиента. Еще более простой интерфейс:
urllib.request.urlretrieve(remoteaddr, filename)
также открывает локальный файл и записывает в него загружаемые байты, что в данном сценарии выполняется вручную. Такой интерфейс удобен, если нужно загрузить файл, но менее полезен, если требуется сразу же обрабатывать его данные.
В любом случае конечный результат один и тот же: требуемый файл, находящийся на сервере, оказывается на компьютере клиента. Вывод этого сценария такой же, как в первоначальной версии, но на этот раз мы не пытаемся автоматически открыть загруженный файл (я изменил пароль в адресе URL, чтобы не искушать судьбу):
C:\…\PP4E\Internet\Ftp> getone-urllib.py Pswd?
Downloading ftp://lutz:xxxxxx@ftp.rmi.net/monkeys.jpg;type=i
C:\…\PP4E\Internet\Ftp> fc monkeys.jpg test\monkeys.jpg FC: no differences encountered
C:\…\PP4E\Internet\Ftp> start monkeys.jpg
Дополнительные примеры загрузки файлов с использованием модуля urllib вы найдете в разделе с описанием протокола HTTP, далее в этой главе, а примеры серверных сценариев — в главе 15. Как будет показано в главе 15, такие инструменты, как функция urlopen из модуля urllib. request, позволяют сценариям загружать удаленные файлы и вызывать программы, находящиеся на удаленных серверах, благодаря чему они могут служить удобными инструментами тестирования и использования веб-сайтов. В главе 15 мы также увидим, что модуль urllib.parse включает инструменты форматирования (экранирования) строк URL для обеспечения безопасной передачи.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011