Python Requets库学习总结2

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Python Requets库学习总结2

请求超时

可以使用timeout参数告诉requests在给定的秒数后停止等待响应。几乎所有的生产代码都应该在几乎所有的请求中使用此参数。否则会导致程序无限期挂起:

>>> requests.get('https://gitee.com/', timeout=0.1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ...
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='gitee.com', port=443): Read timed out. (read timeout=0.1)

注意:

timeout不是整个响应的下载时间限制;相反,如果服务器在timeout秒内没有发出响应(更准确地说,如果在timeout秒内底层socket没有接收到任何字节数据),则会引发异常。如果未明确指定timeout,则请求不会超时。

错误和异常

如果出现网络问题(例如DNS故障、拒绝连接等),requests将抛出ConnectionError异常。

如果HTTP请求返回了失败的状态代码,Response.raise_for_statu()将抛出HTTPError

如果请求超时,则会抛出Timeout异常。

如果请求超过了配置的最大重定向次数,则会抛出TooManyRedirects异常。

requests显式抛出的所有异常都继承自requests.exceptions.RequestException

高级用法

Session对象

Session对象允许你跨请求保持某些参数,以及Session实例发出的所有请求的cookie,并将使用urllib3的[连接池](https://urllib3.readthedocs.io/en/latest/reference/index.html#module-urllib3.connectionpool)。因此,如果你向同一主机发出多个请求,将复用底层TCP连接,这可能会显著提高性能(请参见HTTP持久连接)。

Session对象具有主要 requests API的所有方法。

让我们在请求之间保持一些cookie:

>>> s = requests.Session()
>>> s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
<Response [200]>
>>> r = s.get('https://httpbin.org/cookies')
>>> r.text
'{\n  "cookies": {\n    "sessioncookie": "123456789"\n  }\n}\n'
>>>

Seesion对象还可以用于向请求方法提供默认数据。这是通过向Session对象属性提供数据来实现的:

>>> s = requests.Session()
>>> s.auth = ('user', 'pass')
>>> s.headers.update({'x-test': 'true'})
# 'x-test'和'x-test2'请求头随请求发送了
>>> s.headers.update({'x-test': 'true'})
>>> s.get('https://httpbin.org/headers', headers={'x-test2': 'true'})
<Response [200]>

传递给请求方法的任何字典都将与会话级别设置的值合并。方法级别的参数会覆盖会话级别的参数。

然而,请注意,即使使用会话,方法级参数也不能跨请求保持。本示例将只在发送第一个请求发送cookie,而不发送第二个请求

>>> s = requests.Session()
>>> r = s.get('https://httpbin.org/cookies', cookies={'from-my': 'browser'})
>>> r.text
'{\n  "cookies": {\n    "from-my": "browser"\n  }\n}\n'
>>> r = s.get('https://httpbin.org/cookies')
>>> r.text
'{\n  "cookies": {}\n}\n'

Cookie utility functions to manipulate Session.cookies

如果想手动向Session添加Cookie,那么使用 Cookie utility functions来操作Session.cookies

Session对象也可以用作上下文管理器

>>> with requests.Session() as s:
...     s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
...
<Response [200]>
>>>

这将确保在退出with块后立即关闭会话,即使发生未处理的异常。

Remove a Value From a Dict Parameter
Sometimes you’ll want to omit session-level keys from a dict parameter. To do this, you simply set that key’s value to `None` in the method-level parameter. It will automatically be omitted.
从字典参数中删除值
有时,你需要从dict参数中忽略会话级别的键。为此,只需在方法级参数中将该键的值设置为“None”即可。它将被自动忽略。

Session中包含的所有值都可以直接使用。参见Session API Docs了解更多信息。

请求和响应对象

示例:获取响应头和请求头

>>> r = s.get('https://httpbin.org')
>>> r.headers # 获取响应头
{'Date': 'Mon, 13 Mar 2023 15:43:41 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '9593', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
>>> r.request.headers
{'User-Agent': 'python-requests/2.27.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': 'sessioncookie=123456789'}
>>>

Prepared requests

每当收到来自某个API调用或者Session调用的Response对象,request属性实际上是所使用的PreparedRequest。在某些情况下,你可能希望在发送请求之前对请求体或请求头(或其他任何内容)做一些额外的工作。简单的做法如下:

from requests import Request, Session
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = req.prepare()
# do something with prepped.body
prepped.body = 'No, I want exactly this as the body.'
# do something with prepped.headers
del prepped.headers['Content-Type']
resp = s.send(prepped,
    stream=stream,
    verify=verify,
    proxies=proxies,
    cert=cert,
    timeout=timeout
)
print(resp.status_code)

However, the above code will lose some of the advantages of having a requests Session object. In particular, Session-level state such as cookies will not get applied to your request. To get a PreparedRequest with that state applied, replace the call to Request.prepare() with a call to Session.prepare_request(), like this:

由于你没有对Request对象执行任何特殊操作,因此您可以立即prepare它并修改PreparedRequest对象。然后将其与发送给requests.*Session.*的其它参数一起发送。

然而,上述代码将失去使用requests Session对象的一些优点。特别是Session级别的状态,比如cookie将不会应用于你的请求。如果需要获取应用了那些状态的 PreparedRequest,替换 Request.prepare() 调用为Session.prepare_request(),像这样:

from requests import Request, Session
s = Session()
req = Request('GET',  url, data=data, headers=headers)
prepped = s.prepare_request(req)
# do something with prepped.body
prepped.body = 'Seriously, send exactly these bytes.'
# do something with prepped.headers
prepped.headers['Keep-Dead'] = 'parrot'
resp = s.send(prepped,
    stream=stream,
    verify=verify,
    proxies=proxies,
    cert=cert,
    timeout=timeout
)
print(resp.status_code)

When you are using the prepared request flow, keep in mind that it does not take into account the environment. This can cause problems if you are using environment variables to change the behaviour of requests. For example: Self-signed SSL certificates specified in REQUESTS_CA_BUNDLE will not be taken into account. As a result an SSL: CERTIFICATE_VERIFY_FAILED is thrown. You can get around this behaviour by explicitly merging the environment settings into your session:

当你使用prepared request请求时,请记住它没有考虑环境。如果你正使用环境变量来更改请求的行为,这可能会导致问题。例如:在REQUESTS_CA_BUNDLE中指定的自签名SSL证书将不起作用,结果引发了SSL:CERTIFICATE_VERIFY_FAILED。你可以通过将环境设置显式合并到Session中来避免这种行为:

from requests import Request, Session
s = Session()
req = Request('GET', url)
prepped = s.prepare_request(req)
# Merge environment settings into session
settings = s.merge_environment_settings(prepped.url, {}, None, None, None)
resp = s.send(prepped, **settings)
print(resp.status_code)

HTTP Basic 验证

>>> from requests.auth import HTTPBasicAuth
>>> auth = HTTPBasicAuth('your_username', 'your_password')
>>> r = requests.post(url='you_target_url', data=body, auth=auth)

SSL证书验证

requests验证HTTPS请求的SSL证书,就像web浏览器一样。默认情况下,SSL验证已启用,如果无法验证证书,请求将抛出SSLError:

>>> requests.get('https://requestb.in')
requests.exceptions.SSLError: hostname 'requestb.in' doesn't match either of '*.herokuapp.com', 'herokuapp.com'

你可以使用verify参数传递拥有受信任CA的证书的CA_BUNDLE文件的路径或者目录:

>>> requests.get('https://github.com', verify='/path/to/certfile')

或者

s = requests.Session()
s.verify = '/path/to/certfile'

注意:

如果verify设置为目录的路径,则必须使用OpenSSL提供的c_rehash实用程序处理该目录。

还可以通过REQUESTS_CA_BUNDLE环境变量指定此受信任CA列表。如果未设置REQUESTS_CA_BUNDLE,将使用CURL_CA_BUNDLE

如果将verify设置为False,则requests也可以忽略SSL证书验证:

>>> requests.get('https://kennethreitz.org', verify=False)
<Response [200]>

请注意,当verify设置为False时,Requests将接受服务器提供的任何TLS证书,并将忽略主机名不匹配,或过期的证书,这将使你的应用程序容易受到中间人(MitM)攻击。在本地开发或测试期间,将verify设置为False可能很有用。

默认情况下,verify设置为True。选项verify仅适用于主机证书。

客户端证书

你还可以将本地证书指定为客户端证书、单个文件(包含私钥和证书)或两个文件路径的元组

>>> requests.get('https://kennethreitz.org', cert=('/path/client.cert', '/path/client.key'))
<Response [200]>

或者:

s = requests.Session()
s.cert = '/path/client.cert'

警告

本地证书的私钥必须为未加密的。当前,Requests不支持加密的私钥

CA证书

Reuests使用来自certific包中的证书. 这允许用户在不更改Requests版本的情况下更新其受信任的证书。

在2.16版本之前,Requests捆绑了一组其信任的根CA证书,证书来源于Mzillatruststore。每个Request版本只更新一次证书。当未安装certific时,当使用较旧版本的requests时,这会导致证书包非常过时。

为了安全起见,我们建议经常升级certific

Body内容工作流

默认情况下,当你发出一个请求时,将立即下载响应的正文。你可以使用stream参数覆盖此行为并延迟下载响应主体直到访问response.content属性

tarball_url = 'https://github.com/psf/requests/tarball/main'
r = requests.get(tarball_url, stream=True)

此时,仅仅响应头被下载,且连接保持打开状态,因此,允许我们有条件的检索内容:

if int(r.headers.get('content-length')) < TOO_LONG:
  content = r.content
  ...

您可以使用 Response.iter_content()Response.iter_lines() 方法进一步控制工作流。或者,可以从位于Response.raw的底层的urllib3.HTTPResponse 中读取未编码的主体.

如果在发出请求时将stream设置为True,则requests无法释放连接回连接池,除非读取完所有数据或调用Response.close。这可能导致连接效率低下。如果你发现自己在使用stream=True时部分读取请求体(或根本没有读取它们),则应在with语句中发出请求,以确保连接最终处于关闭状态:

with requests.get('https://httpbin.org/get', stream=True) as r:
    # Do things with the response here.

Keep-Alive

多亏了urllib3keep-alive在Session中是100%自动的!你在Session发出的任何请求都将自动重用合适的连接!

注意,只有在读取了所有响应体数据后,才会将连接释放回连接池以供重用;请确保将stream设置为False或读取Response对象的content属性。

流式上传

requests支持流式上传,允许发送大型流或文件,而无需将其读入内存。要流式传输和上传,只需为请求体提供一个类似文件的对象:

with open('massive-body', 'rb') as f:
    requests.post('http://some.url/streamed', data=f)

警告

强烈建议以二进制模式打开文件。这是因为requests可能会尝试为你提供Content-Length请求头,如果这样做,该请求头值将被设置为文件中的字节数。如果以文本模式打开文件,可能会发生错误。

分块编码(Chunk-Encoded)请求

requests 还支持传出和传入请求的分块传输编码。要发送块编码请求,只需简单的为请求体提供一个生成器(或任何没有长度的迭代器)

def gen():
    yield 'hi'
    yield 'there'
requests.post('http://some.url/chunked', data=gen())

对于分块编码请求的响应,最好使用Response.iter_content()对数据进行迭代。在理想情况下,将在请求上设置stream=True,在这种情况下,可以通过使用值为Nonechunk_size参数调用iter_content来逐块迭代。如果要设置块的最大大小,可以将chunk_size参数设置为任意目标大小整数。

POST 多个分部编码(Multipart-Encoded)文件

你可以在一个请求中发送多个文件。例如,假设你要将图像文件上载到具有多个文件字段“images”的HTML表单:

<input type="file" name="images" multiple="true" required="true"/>

为此,只需将files设置为(form_field_name,file_info)的元组列表:

>>> url = 'https://httpbin.org/post'
>>> multiple_files = [
...     ('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
...     ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
>>> r = requests.post(url, files=multiple_files)
>>> r.text
>>> r.text
'{\n  "args": {}, \n  "data": "", \n  "files": {\n    "images": "data:image/png;base64,iVBORw0KGgoAAAAN...=="\n  }, \n  "form": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "1800", \n    "Content-Type": "multipart/form-data; boundary=771ef90459071106c5f47075cbca2659", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.27.1", \n    "X-Amzn-Trace-Id": "Root=1-641122ea-10a6271f0fdf488c70cf90e9"\n  }, \n  "json": null, \n  "origin": "183.62.127.25", \n  "url": "https://httpbin.org/post"\n}\n'

事件钩子(Event Hooks)

requests拥有一个hook系统,可用于控制请求过程的部分,或者信号事件处理。

可用的hooks:

  • response:
    请求生成的响应

通过将{hook_name:callback_function}字典传递给hooks请求参数,可以按每个请求分配一个钩子函数:

hooks={'response': print_url}

callback_function将接收一数据块(a chunk of data)作为其第一个参数。

def print_url(r, *args, **kwargs):
    print(r.url)

回调函数必须处理其自己的异常。任何为处理的异常,都不会以静默方式传递,因此应该由代码调用请求来处理。

如果回调函数返回某个值,则假定它将替换传入的数据。如果函数不返回任何内容,则不产生任何影响

def record_hook(r, *args, **kwargs):
    r.hook_called = True
    return r

让我们在运行时打印一些请求方法参数:

>>> requests.get('https://httpbin.org/', hooks={'response': print_url})
https://httpbin.org/
<Response [200]>

可以添加多个钩子到单个请求中,如下,一次调用两个钩子函数:

>>> r = requests.get('https://httpbin.org/', hooks={'response': [print_url, record_hook]})
>>> r.hook_called
True

还可以为Session实例添加钩子,这样添加的任何钩子都将在向会话发出的每个请求中被调用。例如:

>>> s = requests.Session()
>>> s.hooks['response'].append(print_url)
>>> s.get('https://httpbin.org/')
 https://httpbin.org/
 <Response [200]>

如果Session实例可个钩子函数,那么将按钩子的添加顺序调用这些钩子。

自定义身份验证

requests 请求支持自定义身份验证机制。

作为auth参数传递给请求方法的任何可调用对象都有机会在发送请求之前修改请求。

身份验证实现为AuthBase的子类,并且易于定义。requests在requests.auth中提供了两种常见的身份验证方案实现:HTTPBasicAuthHTTPDigestAuth.

假设我们有一个web服务,它只有在X-Pizza请求头设置为密码值时才会响应。这不太可能,暂且还是顺着它:

from requests.auth import AuthBase
class PizzaAuth(AuthBase):
    """Attaches HTTP Pizza Authentication to the given Request object."""
    def __init__(self, username):
        # setup any auth-related data here
        self.username = username
    def __call__(self, r):
        # modify and return the request
        r.headers['X-Pizza'] = self.username
        return r

然后,发送请求

>>> requests.get('http://pizzabin.org/admin', auth=PizzaAuth('kenneth'))
<Response [200]>

流式请求

使用Response.iter_lines() ,可以很轻易的迭代流式API,比如 Twitter Streaming API。简单的设置 streamTrue 并且使用iter_lines对响应进行迭代:

import json
import requests
r = requests.get('https://httpbin.org/stream/20', stream=True)
for line in r.iter_lines():
    # filter out keep-alive new lines
    if line:
        decoded_line = line.decode('utf-8')
        print(json.loads(decoded_line))

decode_unicode=TrueResponse.iter_lines() 或者Response.iter_content()配合使用时,如果服务器未提供编码,则需要提供编码:

r = requests.get('https://httpbin.org/stream/20', stream=True)
if r.encoding is None:
    r.encoding = 'utf-8'
for line in r.iter_lines(decode_unicode=True):
    if line:
        print(json.loads(line))

警告

iter_lines 不是可重入安全的。多次调用此方法会导致一些接收到的数据丢失。如果需要从多个地方调用它,请使用生成的迭代器对象:

lines = r.iter_lines()
# Save the first line for later or just skip it
first_line = next(lines)
for line in lines:
    print(line)

代理

如果你需要使用代理,可在任何请求方法的proxys参数中为单个请求配置代理

import requests
proxies = {
  'http': 'http://10.10.1.10:3128',
  'https': 'http://10.10.1.10:1080',
}
requests.get('http://example.org', proxies=proxies)

可选的,可以一次性为整个Session配置代理。

import requests
proxies = {
  'http': 'http://10.10.1.10:3128',
  'https': 'http://10.10.1.10:1080',
}
session = requests.Session()
session.proxies.update(proxies)
session.get('http://example.org')

警告

session.proxies提供的值可能被环境代理(由urllib.request.getproxys返回的值)覆盖,所以为了确保在环境代理存在的情况下,也使用给定代理,显示为所有单个请求指定proxies参数,如上述一开始所述。

如果没有为请求设置proxies请求参数的情况下,requests会尝试读取由标准环境变量 http_proxy, https_proxy, no_proxyall_proxy定义的代理配置。这些变量名称可大写。所以,可以通过这些变量配置为请求设置代理(请根据实际需要配置):

linux:

$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="http://10.10.1.10:1080"
$ export ALL_PROXY="socks5://10.10.1.10:3434"
$ python
>>> import requests
>>> requests.get('http://example.org')

win:

set HTTP_PROXY=http://10.10.1.10:3128
>>> import requests
>>> requests.get('http://example.org')

要对代理使用HTTP基本身份验证,请在上述任意代理配置入口中使用http://user:password@host/语法:

$ export HTTPS_PROXY="http://user:pass@10.10.1.10:1080"
$ python
>>> proxies = {'http': 'http://user:pass@10.10.1.10:3128/'}

警告

将敏感的用户名和密码信息存储在环境变量或版本控制的文件中会带来安全风险,强烈建议不要这样做。

如果要为特定shema和主机提供代理,请使用scheme://hostnameproxies字典参数的键来设置代理。这将匹配给定scheme和确切主机名的任何请求。

proxies = {'http://10.20.1.128': 'http://10.10.1.10:5323'}

注意,代理URL必须包含schema。

最后需要注意的,为https连接设置代理,通常需要所在本机机器信任代理根证书。默认的,可以通过以下代码查找requests信任的证书列表:

from requests.utils import DEFAULT_CA_BUNDLE_PATH
print(DEFAULT_CA_BUNDLE_PATH)

通过将 REQUESTS_CA_BUNDLE (or CURL_CA_BUNDLE) 环境变量设置为另一个文件路径,可以覆盖此证书路径:

$ export REQUESTS_CA_BUNDLE="/usr/local/myproxy_info/cacert.pem"
$ export https_proxy="http://10.10.1.10:1080"
$ python
>>> import requests
>>> requests.get('https://example.org')

SOCKS

版本2.10.0中新增

除了基本的HTTP代理之外,requests还支持使用SOCKS协议的代理。这是一项可选功能,要求在使用前安装其他第三方库

可通过pip获取该功能需要的依赖:

$ python -m pip install requests[socks]

安装依赖后,使用SOCKS代理就同使用HTTP代理一样简单:

proxies = {
    'http': 'socks5://user:pass@host:port',
    'https': 'socks5://user:pass@host:port'
}

使用 socks5 会导致DNS解析发生在客户端上,而不是代理服务器上。这与curl保持一致,curl使用scheme来决定是在客户端还是代理服务器上进行DNS解析。如果要解析代理服务器上的域,请使用socks5h作为scheme

编码

当收到响应时,并访问 Response.text属性时,requests会猜测用于解码响应体的编码。requests将首先检查HTTP请求头中的编码,如果不存在,则使用charset_normalizerchardet尝试猜测编码。

如果安装了chardetrequests将使用它,但对于python3来说,chardet不再是强制依赖项。

当安装requests时,没有指定 [use_chardet_on_py3],并且chardet尚未安装时,requests将使用charset normalizer来猜测编码。

requests不会猜测编码的唯一情况是HTTP请求头中不存在显示字符集且Content-Type请求头包含text。在这种情况下,RFC 2616指定默认字符集必须是ISO-8859-1。requests遵循该规范。如果需要不同的编码,您可以手动设置Response.conding属性,或使用原始Response.content

Link请求头

许多HTTP API具有link请求头。它们使API更加自我描述和可发现。

GitHub 在API中将这些用于分页

>>> url = 'https://api.github.com/users/kennethreitz/repos?page=1&per_page=10'
>>> r = requests.head(url=url)
>>> r.headers['link']
'<https://api.github.com/user/119893/repos?page=2&per_page=10>; rel="next", <https://api.github.com/user/119893/repos?page=5&per_page=10>; rel="last"'

requests 将自动解析这link请求头并且让它们更容易被使用:

>>> r.links["next"]
{'url': 'https://api.github.com/user/119893/repos?page=2&per_page=10', 'rel': 'next'}
>>> r.links["last"]
{'url': 'https://api.github.com/user/119893/repos?page=5&per_page=10', 'rel': 'last'}

传输适配器(Transport Adapters)

从v1.0.0开始,requests 已模块化内部设计。这样做的部分原因是为了实现传输适配器,最初在此处描述. 传输适配器提供了一种机制来定义某个HTTP服务的交互方法。特别是,它们允许你应用每个服务的配置。

requests附带单个传输适配器HTTPAdapter. 此适配器使用功能强大的urllib3提供与HTTP和HTTPS的默认请求交互。当初始化 requests Session 时,其中一个附加到Session 对象表示HTTP,一个表示HTTPS。

户能够创建和使用自己的具备特定功能的传输适配器。一旦创建,传输适配器就可以加载到会话对象,并指示它应该应用于哪些web服务。

>>> s = requests.Session()
>>> s.mount('https://github.com/', MyAdapter())

上述mount调用将传输适配器的指定实例注册到URL前缀中。一旦挂载,使用该session发起的,URL以给定前缀开头的任何HTTP请求都将使用给定的传输适配器。

实现传输适配器的许多细节超出了本文档的范围,但是可以看下一个简单SSL使用示例。除此之外,您还可以考虑继承BaseAdapter实现子类适配器。

示例: 指定SSL版本

The requests team has made a specific choice to use whatever SSL version is default in the underlying library (urllib3). Normally this is fine, but from time to time, you might find yourself needing to connect to a service-endpoint that uses a version that isn’t compatible with the default.

You can use Transport Adapters for this by taking most of the existing implementation of HTTPAdapter, and adding a parameter ssl_version that gets passed-through to urllib3. We’ll make a Transport Adapter that instructs the library to use SSLv3:

默认情况下,requests选择使用底层urllib3库中默认的SSL版本。 通常情况下,这是可以的,但有时,您可能会发现自己需要连接到使用与默认版本不兼容的SSL版本的服务端。

为此,可以通过继承HTTPAdapter实现自定义传输适配器,

示例:编写一个适配器,指示库使用SSLv3:

import ssl
from urllib3.poolmanager import PoolManager
from requests.adapters import HTTPAdapter
class Ssl3HttpAdapter(HTTPAdapter):
    """"Transport adapter" that allows us to use SSLv3."""
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections, maxsize=maxsize,
            block=block, ssl_version=ssl.PROTOCOL_SSLv3)

阻塞或非阻塞

有了默认的传输适配器,requests就不会提供任何类型的非阻塞IO。Response.content属性将阻塞,直到下载完整个响应为止。如果你需要更大的粒度,则库的流式传输功能(请参阅流式传输请求)允许单次接收较小数量的响应那日。然而,这些调用仍然是阻塞。

如果您关心阻塞IO的使用,那么有很多项目将请求与Python的异步框架结合在一起。一些很好的例子是 requests-threads, grequests, requests-futures, 和httpx.

超时

大多数对外部服务器的请求都应该附加超时,以防服务器没有及时响应。默认情况下,除非显式设置了超时时间,否则requests不会超时。如果没有超时,你的代码可能会挂起几分钟或更长时间。

连接超时是requests等待客户端建立与远程计算机的socke连接的秒数。将连接超时设置为略大于3的倍数是一种很好的做法,因为3秒是默认的TCP数据包重传窗口.

一旦客户端连接到服务器并发送HTTP请求后,读取超时是客户端等待服务器返回响应的秒数(具体来说,这是客户端等待服务器返回字节数据的秒数。在99.9%的情况下,这是服务器返回第一个字节之前的等待时间)。

如果需要为请求设置一个超时时间,可以为timeout参数指定一个具体的时间值:

r = requests.get('https://github.com', timeout=5)

该超时时间将同时应用于连接超时和读取超时。如果想为连接超时和读取超时分别设置不同的等待时间,可以指定一个元组:

r = requests.get('https://github.com', timeout=(3.05, 27))

如果服务很慢,想让requests一直等待响应直到获取响应,可以指定timeout参数值为None

r = requests.get('https://github.com', timeout=None)
目录
相关文章
|
19天前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
8天前
|
XML 存储 数据库
Python中的xmltodict库
xmltodict是Python中用于处理XML数据的强大库,可将XML数据与Python字典相互转换,适用于Web服务、配置文件读取及数据转换等场景。通过`parse`和`unparse`函数,轻松实现XML与字典间的转换,支持复杂结构和属性处理,并能有效管理错误。此外,还提供了实战案例,展示如何从XML配置文件中读取数据库连接信息并使用。
Python中的xmltodict库
|
16天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
51 4
|
16天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
25 2
|
21天前
|
数据采集 JSON 测试技术
Python爬虫神器requests库的使用
在现代编程中,网络请求是必不可少的部分。本文详细介绍 Python 的 requests 库,一个功能强大且易用的 HTTP 请求库。内容涵盖安装、基本功能(如发送 GET 和 POST 请求、设置请求头、处理响应)、高级功能(如会话管理和文件上传)以及实际应用场景。通过本文,你将全面掌握 requests 库的使用方法。🚀🌟
41 7
|
14天前
|
数据采集 数据可视化 数据挖掘
利用Python进行数据分析:Pandas库实战指南
利用Python进行数据分析:Pandas库实战指南
|
21天前
|
文字识别 自然语言处理 API
Python中的文字识别利器:pytesseract库
`pytesseract` 是一个基于 Google Tesseract-OCR 引擎的 Python 库,能够从图像中提取文字,支持多种语言,易于使用且兼容性强。本文介绍了 `pytesseract` 的安装、基本功能、高级特性和实际应用场景,帮助读者快速掌握 OCR 技术。
37 0
|
1月前
|
Python
pip批量安装Python库 requirement.txt 离线环境无互联网环境下pip安装Python库
pip批量安装Python库 requirement.txt 离线环境无互联网环境下pip安装Python库
124 3
|
5月前
|
开发工具 git Python
安装和使用`libnum`是一个用于数字理论函数的Python库
【6月更文挑战第19天】`libnum`是Python的数字理论函数库。安装可通过`git clone`,进入目录后运行`python setup.py install`,也可用`pip install libnum`。示例:使用`int_to_hex`将十进制数42转换为十六进制字符串&#39;2a&#39;。注意,信息可能已过时,应查最新文档以确保准确性。如遇问题,参考GitHub仓库或寻求社区帮助。
119 1
|
4月前
|
Python
确保你已经安装了`python-barcode`库。如果没有,可以通过pip来安装:
确保你已经安装了`python-barcode`库。如果没有,可以通过pip来安装:
下一篇
无影云桌面