Функции для загрузки сетевых объектов

Простой случай получения 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% скидку новым пользователям на все книги Литрес с нашим промокодом

ПОЛУЧИТЬ СКИДКУ