Python:如果在执行requests.get()时脚本停止会发生什么?

mac*_*azo 15 python http python-requests python-requests-html

我知道它requests.get()提供了一个HTTP接口,以便程序员可以向HTTP服务器发出各种请求.

这告诉我某个端口必须打开,以便请求可以发生.

考虑到这一点,如果脚本被停止(例如,通过键盘中断,那么正在执行脚本的机器仍然连接到互联网),在请求被应答/完成之前会发生什么?

端口/连接是否仍然打开?

端口/连接是否自动关闭?

Mat*_*ory 12

对问题的简短回答是:请求将在任何异常情况下关闭连接,包括KeyboardInterruptSystemExit.

一个 入请求的源代码显示,requests.get最终调用的HTTPAdapter.send方法(这是所有魔术发生).

在方法中可以通过两种方式进行请求send:chunked或not chunked.send我们执行哪个取决于request.bodyContent-Length标头的值:

chunked = not (request.body is None or 'Content-Length' in request.headers)
Run Code Online (Sandbox Code Playgroud)

在请求体是NoneContent-Length已设置的情况下,requests使用以下高级urlopen方法urllib3:

if not chunked:
    resp = conn.urlopen(
        method=request.method,
        url=url,
        body=request.body,
        # ...
    )
Run Code Online (Sandbox Code Playgroud)

该方法的finallyurllib3.PoolManager.urlopen具有处理在try块未成功执行的情况下关闭连接的代码:

clean_exit = False
# ...
try:
    # ...
    # Everything went great!
    clean_exit = True
finally:
    if not clean_exit:
        # We hit some kind of exception, handled or otherwise. We need
        # to throw the connection away unless explicitly told not to.
        # Close the connection, set the variable to None, and make sure
        # we put the None back in the pool to avoid leaking it.
        conn = conn and conn.close()
        release_this_conn = True
Run Code Online (Sandbox Code Playgroud)

在响应可以分块的情况下,请求会降低一些级别并使用由提供的底层低级别连接urllib3.在这种情况下,请求仍然处理异常,它使用在获取连接后立即启动的try/except block 执行此操作,并完成:

low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)

try:
    # ...
except:
    # If we hit any problems here, clean up the connection.
    # Then, reraise so that we can handle the actual exception.
    low_conn.close()
    raise
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果没有错误,连接可能不会关闭,具体取决于您为连接池配置的方式urllib3.在成功执行的情况下,连接被放回连接池(虽然我无法找到一个_put_conn呼叫requests的分块的来源send,这可能是分块的工作流程中的错误).