42

如何使用 Python 的 urllib2 发出“保持活动”HTTP 请求?

4

7 回答 7

34

使用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或更早版本,因为keepalive模块已在版本 3.9.1 中删除

keepalive 模块有一个移植到 Python 3 的端口。

于 2009-06-24T09:56:44.060 回答
13

试试urllib3,它具有以下特性:

  • 对多个请求(HTTPConnectionPool 和 HTTPSConnectionPool)重复使用相同的套接字连接(带有可选的客户端证书验证)。
  • 文件过帐 (encode_multipart_formdata)。
  • 内置重定向和重试(可选)。
  • 支持 gzip 和 deflate 解码。
  • 线程安全和健全安全。
  • 小型且易于理解的代码库,非常适合扩展和构建。如需更全面的解决方案,请查看 Requests。

或更全面的解决方案 - Requests - 从0.8.0开始支持 keep-alive (通过在内部使用 urllib3)并具有以下功能

  • 极其简单的 HEAD、GET、POST、PUT、PATCH、DELETE 请求。
  • Gevent 支持异步请求。
  • 具有 cookie 持久性的会话。
  • 基本、摘要和自定义身份验证支持。
  • 字典的自动格式编码
  • 请求/响应 cookie 的简单字典接口。
  • 多部分文件上传。
  • Unicode、gzip 和 deflate 响应的自动解码。
  • 完全支持 unicode URL 和域名。
于 2011-11-10T22:00:14.213 回答
6

或者查看httplib的 HTTPConnection。

于 2011-05-28T16:54:26.673 回答
5

不幸的是,在 urlgrabber 更改为依赖于 pycurl(支持 keep-alive)后,keepalive.py 于 2009 年 9 月 25 日从 urlgrabber 中删除:

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

于 2011-01-06T02:51:07.950 回答
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
于 2010-01-08T00:05:38.017 回答
3

请避免集体痛苦并改用请求。默认情况下它会做正确的事情并在适用时使用keep-alive。

于 2013-01-11T16:39:05.970 回答
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
于 2014-11-23T15:06:01.817 回答