Функции для загрузки сетевых объектов
Простой случай получения WWW–объекта по известному URL показан в следующем примере:
import urllib
doc = urllib.urlopen("http://python.onego.ru").read()
print doc[:40]
Функция urllib.urlopen() создает файлоподобный объект, который читает методом read(). Другие методы этого объекта: readline(), readlines(), fileno(), close() работают как и у обычного файла, а также есть метод info(), который возвращает соответствующий полученному с сервера Message–объект. Этот объект можно использовать для получения дополнительной информации:
>>> import urllib
>>> f = urllib.urlopen("http://python.onego.ru")
>>> print f.info()
Date: Sat, 25 Dec 2004 19:46:11 GMT
Server: Apache/1.3.29 (Unix) PHP/4.3.10
Content–Type: text/html; charset=windows–1251
Content–Length: 4291
>>> print f.info()['Content–Type']
text/html; charset=windows–1251
С помощью функции urllib.urlopen() можно делать и более сложные вещи, например, передавать web–серверу данные формы. Как известно, данные заполненной web–формы могут быть переданы на web–сервер с использованием метода GET или метода POST. Метод GET связан с кодированием всех передаваемых параметров после знака «?» в URL, а при методе POST данные передаются в теле HTTP–запроса. Оба варианта передачи представлены ниже:
import urllib
data = {"search»: "Python"}
enc_data = urllib.urlencode(data)
# метод GET
f = urllib.urlopen("http://searchengine.com/search" + "?" + enc_data)
print f.read()
# метод POST
f = urllib.urlopen("http://searchengine.com/search", enc_data)
print f.read()
В некоторых случаях данные имеют повторяющиеся имена. В этом случае в качестве параметра urllib.urlencode() можно использовать вместо словаря последовательность пар имя–значение:
>>> import urllib
>>> data = [("n", "1"), ("n", "3"), ("n", "4"), ("button", "Привет"),]
>>> enc_data = urllib.urlencode(data)
>>> print enc_data
n=1&n=3&n=4&button=%F0%D2%C9%D7%C5%D4
Модуль urllib позволяет загружать web–объекты через прокси–сервер. Если ничего не указывать, будет использоваться прокси–сервер, который был задан принятым в конкретной ОС способом. В Unix прокси–серверы задаются в переменных окружения http_proxy, ftp_proxy и т.п., в Windows прокси–серверы записаны в реестре, а в Mac OS они берутся из конфигурации Internet. Задать прокси–сервер можно и как именованный параметр proxies к urllib.urlopen():
# Использовать указанный прокси
proxies = {'http': 'http://www.proxy.com:3128'}
f = urllib.urlopen(some_url, proxies=proxies)
# Не использовать прокси
f = urllib.urlopen(some_url, proxies={})
# Использовать прокси по умолчанию
f = urllib.urlopen(some_url, proxies=None)
f = urllib.urlopen(some_url)
Функция urlretrieve() позволяет записать заданный URL сетевой объект в файл. Она имеет следующие параметры:
urllib.urlretrieve(url[, filename[, reporthook[, data]]])
Здесь url — URL сетевого объекта, filename — имя локального файла для помещения объекта, reporthook — функция, которая будет вызываться для сообщения о состоянии загрузки, data — данные для метода POST (если он используется). Функция возвращает кортеж (filepath, headers), где filepath — имя локального файла, в который закачан объект, headers — результат метода info() для объекта, возвращенного urlopen().
Для обеспечения интерактивности функция urllib.urlretrieve() вызывает время от времени функцию, заданную в reporthook(). Этой функции передаются три аргумента: количество принятых блоков, размер блока и общий размер принимаемого объекта в байтах (если он неизвестен, этот параметр равен–1).
В следующем примере программа принимает большой файл и, чтобы пользователь не скучал, пишет процент от выполненной загрузки и предполагаемое оставшееся время:
FILE = 'boost–1.31.0–9.src.rpm'
URL = 'http://download.fedora.redhat.com/pub/fedora/linux/core/3/SRPMS/' + FILE
def download(url, file):
import urllib, time
start_t = time.time()
def progress(bl, blsize, size):
dldsize = min(bl*blsize, size)
if size != -1:
p = float(dldsize) / size
try:
elapsed = time.time() - start_t
est_t = elapsed / p — elapsed
except:
est_t = 0
print "%6.2f %% %6.0f s %6.0f s %6i / %-6i bytes" % (
p*100, elapsed, est_t, dldsize, size)
else:
print "%6i / %-6i bytes" % (dldsize, size)
urllib.urlretrieve(URL, FILE, progress)
download(URL, FILE)
Эта программа выведет примерно следующее (процент от полного объема закачки, прошедшие секунды, предполагаемое оставшееся время, закачанные байты, полное количество байтов):
0.00 % 1 s 0 s 0 / 6952309 bytes
0.12 % 5 s 3941 s 8192 / 6952309 bytes
0.24 % 7 s 3132 s 16384 / 6952309 bytes
0.35 % 10 s 2864 s 24576 / 6952309 bytes
0.47 % 12 s 2631 s 32768 / 6952309 bytes
0.59 % 15 s 2570 s 40960 / 6952309 bytes
0.71 % 18 s 2526 s 49152 / 6952309 bytes
0.82 % 20 s 2441 s 57344 / 6952309 bytes
...
Больше книг — больше знаний!
Заберите 30% скидку новым пользователям на все книги Литрес с нашим промокодом
ПОЛУЧИТЬ СКИДКУ