Опубликован: 22.12.2005 | Уровень: для всех | Доступ: платный
Лекция 9:

Сетевые приложения на Python

Модули для клиента WWW

Стандартные средства языка Python позволяют получать из программы доступ к объектам WWW как в простых случаях, так и при сложных обстоятельствах, в частности при необходимости передавать данные формы, идентификации, доступа через прокси и т.п.

Стоит отметить, что при работе с WWW используется в основном протокол HTTP, однако WWW охватывает не только HTTP, но и многие другие схемы (FTP, gopher, HTTPS и т.п.). Используемая схема обычно указана в самом начале URL.

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

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

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?

 

Павел Ялганов
Павел Ялганов

Скажите экзамен тоже будет ввиде теста? или там будет какое то практическое интересное задание?

Максим Чиндясов
Максим Чиндясов
Россия, Нижний Новгород
Ольга Коваль
Ольга Коваль
Беларусь, Минск