如何使用Python的urllib2创建“保持活跃”的HTTP请求?
答案 0 :(得分:33)
使用urlgrabber库。这包括支持HTTP 1.1和keepalive的urllib2的HTTP处理程序:
>>> 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或更早版本,因为版本3.9.1中已删除keepalive模块
Python 3有一个port的keepalive模块。
答案 1 :(得分:13)
尝试具有以下功能的urllib3:
或更全面的解决方案 - Requests - 支持来自version 0.8.0的保持活动(通过内部使用urllib3)并具有以下features:
答案 2 :(得分:7)
或者查看httplib的HTTPConnection。
答案 3 :(得分:5)
不幸的是,在urlgrabber更改为依赖pycurl(支持keep-alive)之后,2009年9月25日,keepalive.py从urlgrabber中删除了以下更改:
http://yum.baseurl.org/gitweb?p=urlgrabber.git;a=commit;h=f964aa8bdc52b29a2c137a917c72eecd4c4dda94
但是,您仍然可以在此处获取keepalive.py的最新修订版:
答案 4 :(得分:4)
请注意,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
答案 5 :(得分:3)
请避免集体痛苦并改用Requests。默认情况下它会做正确的事情,如果适用的话,使用keep-alive。
答案 6 :(得分:0)
这里有一个类似的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