Как ускорить работу urlib2 в Python при выполнении нескольких запросов - PullRequest
20 голосов
/ 06 января 2010

Я делаю несколько http-запросов к определенному хосту, используя библиотеку python urllib2. Каждый раз, когда делается запрос, создается новое соединение TCP и HTTP, которое занимает заметное количество времени. Есть ли способ сохранить соединение tcp / http с помощью urllib2?

Ответы [ 3 ]

27 голосов
/ 08 июня 2011

Если вы переключитесь на httplib , у вас будет более точный контроль над основным соединением.

Например:

import httplib

conn = httplib.HTTPConnection(url)

conn.request('GET', '/foo')
r1 = conn.getresponse()
r1.read()

conn.request('GET', '/bar')
r2 = conn.getresponse()
r2.read()

conn.close()

При этом будет отправлено 2 HTTP-запроса GET по одному и тому же базовому TCP-соединению.

2 голосов
/ 08 июня 2011

Я использовал стороннюю библиотеку urllib3 для хорошего эффекта в прошлом. Он предназначен для дополнения urllib2 путем объединения подключений для повторного использования.

Модифицированный пример из вики :

>>> from urllib3 import HTTPConnectionPool
>>> # Create a connection pool for a specific host
... http_pool = HTTPConnectionPool('www.google.com')
>>> # simple GET request, for example
... r = http_pool.urlopen('GET', '/')
>>> print r.status, len(r.data)
200 28050
>>> r = http_pool.urlopen('GET', '/search?q=hello+world')
>>> print r.status, len(r.data)
200 79124
0 голосов
/ 23 ноября 2014

Если вам нужно что-то более автоматическое, чем простой httplib, это может помочь, хотя и не безопасно.

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
...