Язык программирования Python

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


Простой случай получения 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 ...


Содержание раздела