📅  最后修改于: 2023-12-03 15:35:32.156000             🧑  作者: Mango
urllib3
Python库介绍urllib3
是一个功能丰富,线程安全且具有文档的 HTTP 客户端库,适用于 Python 2.7 和 3.x。它具有以下特征:
使用 pip
安装 urllib3
:
pip install urllib3
导入 urllib3
之后,您就可以创建 PoolManager
的实例,并使用它来发出 HTTP 请求。下面是一个简单的示例:
import urllib3
if __name__ == '__main__':
http = urllib3.PoolManager()
url = "https://www.baidu.com"
response = http.request('GET', url)
print(response.status)
print(response.data.decode())
该示例向百度发送请求,并打印出响应状态码和响应内容。
您可以在 request
方法中传递诸如 headers
,data
和 params
等可选参数来定制您的请求。例如:
response = http.request('POST', url,
headers={'Content-Type': 'application/json'},
body=json.dumps({"name": "小明", "age": 18}).encode(),
)
就像上面示例中创建了一个 PoolManager
一样,urllib3
中的连接池非常强大且灵活。您可以轻松地调整连接池的大小,并在整个应用程序或模块中进行共享。
一个常见的模式是在模块中创建一个连接池,并在所有函数之间共享它。下面是一个简单的示例:
import urllib3
http = urllib3.PoolManager(num_pools=2, maxsize=10)
def foo():
r = http.request('GET', 'https://www.google.com.hk/')
print(r.status)
print(r.data.decode())
def bar():
r = http.request('GET', 'https://www.google.com.hk/')
print(r.status)
print(r.data.decode())
连接池通过 num_pools
和 maxsize
参数进行配置。这两个参数决定了连接池的最大数量和每个连接池中连接的最大数量。
如果您需要管理多个连接池,可以使用 PoolManager
的子类来做到这一点。例如,您可以创建不同的连接池以与不同的主机进行通信:
class MyPoolManager(urllib3.PoolManager):
def __init__(self, *args, **kwargs):
self.host_map = {}
super().__init__(*args, **kwargs)
def request(self, method, url, *args, **kwargs):
parsed_url = urllib3.util.parse_url(url)
host = parsed_url.host
if host not in self.host_map:
self.host_map[host] = self._new_pool(host)
return self.host_map[host].request(method, url, *args, **kwargs)
def _new_pool(self, host):
return urllib3.PoolManager().ConnectionPool(host)
http = MyPoolManager()
在默认情况下,urllib3
提供的连接池只返回存活的连接。如果您想自定义连接管理,例如超时或升级到WebSocket等高级协议,则可以使用两个功能:urllib3.util.retry
和 urllib3.util.Timeout
。
例如,以下代码说明了如何定义包装器以使用重试和超时功能:
import logging
import urllib3
from urllib3.util.retry import Retry
from urllib3.util.timeout import Timeout
logging.basicConfig()
logger = logging.getLogger(__name__)
def safe_request(url):
http = urllib3.PoolManager(
retries=Retry(
total=5,
backoff_factor=0.2,
status_forcelist=[500, 502, 503, 504],
method_whitelist=["HEAD", "GET", "OPTIONS"]
),
timeout=Timeout(connect=2.0, read=2.0)
)
try:
r = http.request('GET', url)
logger.debug('url=%s status=%s', url, r.status)
return r.data
except Exception as e:
logger.debug('url=%s error=%r', url, e)
return None
在上面的示例中,我们使用了 Retry
和 Timeout
来为请求增加保护措施。如果请求失败,则会重试共 5 次。如果在2秒内未与服务器建立连接或读取数据,则会超时。