Python urllib2 с поддержкой активности - PullRequest
42 голосов
/ 24 июня 2009

Как я могу сделать HTTP-запрос "keep alive", используя urllib2 в Python?

Ответы [ 7 ]

33 голосов
/ 24 июня 2009

Используйте библиотеку urlgrabber . Это включает в себя обработчик HTTP для urllib2, который поддерживает HTTP 1.1 и keepalive:

>>> import urllib2
>>> from urlgrabber.keepalive import HTTPHandler
>>> keepalive_handler = HTTPHandler()
>>> opener = urllib2.build_opener(keepalive_handler)
>>> urllib2.install_opener(opener)
>>> 
>>> fo = urllib2.urlopen('http://www.python.org')

Примечание: вы должны использовать urlgrabber версии 3.9.0 или более ранней, так как модуль keepalive был удален в версии 3.9.1

Существует порт модуля keepalive для Python 3.

13 голосов
/ 11 ноября 2011

Попробуйте urllib3 , который имеет следующие функции:

  • Повторное использование одного и того же сокета для нескольких запросов (HTTPConnectionPool и HTTPSConnectionPool) (с необязательной проверкой сертификата на стороне клиента).
  • Публикация файла (encode_multipart_formdata).
  • Встроенное перенаправление и повторные попытки (необязательно).
  • Поддерживает декодирование gzip и deflate.
  • Потокобезопасен и безопасен для здоровья.
  • Небольшая и простая для понимания кодовая база, идеально подходящая для расширения и расширения. Для более полного решения взгляните на Запросы.

или гораздо более комплексное решение - Запросы - которое поддерживает поддержку активности с версии 0.8.0 (с помощью внутреннего использования urllib3) и имеет следующие функции :

  • Чрезвычайно простые запросы HEAD, GET, POST, PUT, PATCH, DELETE.
  • Поддержка Gevent для асинхронных запросов.
  • Сессии с сохранением cookie.
  • Поддержка базовой, дайджестной и пользовательской аутентификации.
  • Автоматическое кодирование форм словарей
  • Простой словарный интерфейс для файлов cookie запросов / ответов.
  • Загрузка нескольких файлов.
  • Автоматическое декодирование Unicode, gzip и deflate ответов.
  • Полная поддержка URL-адресов Юникода и доменных имен.
7 голосов
/ 28 мая 2011

Или посмотрите HTTPConnection httplib .

5 голосов
/ 06 января 2011

К сожалению, keepalive.py был удален из urlgrabber 25 сентября 2009 года следующим изменением после изменения urlgrabber в зависимости от pycurl (который поддерживает keep-alive):

http://yum.baseurl.org/gitweb?p=urlgrabber.git;a=commit;h=f964aa8bdc52b29a2c137a917c72eecd4c4dda94

Однако вы можете получить последнюю версию keepalive.py здесь:

http://yum.baseurl.org/gitweb?p=urlgrabber.git;a=blob_plain;f=urlgrabber/keepalive.py;hb=a531cb19eb162ad7e0b62039d19259341f37f3a6

4 голосов
/ 08 января 2010

Обратите внимание, что urlgrabber не полностью работает с Python 2.6. Я исправил проблемы (я думаю), внеся следующие изменения в keepalive.py.

В keepalive.HTTPHandler.do_open () удалить это

     if r.status == 200 or not HANDLE_ERRORS:
         return r

И вставить это

     if r.status == 200 or not HANDLE_ERRORS:
         # [speedplane] Must return an adinfourl object
         resp = urllib2.addinfourl(r, r.msg, req.get_full_url())
         resp.code = r.status
         resp.msg = r.reason
         return resp
3 голосов
/ 11 января 2013

Пожалуйста, избегайте коллективной боли и используйте Запросы . По умолчанию он будет работать правильно и использовать keep-alive, если применимо.

0 голосов
/ 23 ноября 2014

Вот несколько похожий urlopen (), который поддерживает работу, хотя и не безопасен для потоков.

try:
    from http.client import HTTPConnection, HTTPSConnection
except ImportError:
    from httplib import HTTPConnection, HTTPSConnection
import select
connections = {}


def request(method, url, body=None, headers={}, **kwargs):
    scheme, _, host, path = url.split('/', 3)
    h = connections.get((scheme, host))
    if h and select.select([h.sock], [], [], 0)[0]:
        h.close()
        h = None
    if not h:
        Connection = HTTPConnection if scheme == 'http:' else HTTPSConnection
        h = connections[(scheme, host)] = Connection(host, **kwargs)
    h.request(method, '/' + path, body, headers)
    return h.getresponse()


def urlopen(url, data=None, *args, **kwargs):
    resp = request('POST' if data else 'GET', url, data, *args, **kwargs)
    assert resp.status < 400, (resp.status, resp.reason, resp.read())
    return resp
...