Python:如果在执行requests.get()时脚本停止,会发生什么情况?
我知道Python:如果在执行requests.get()时脚本停止,会发生什么情况?,python,http,python-requests,python-requests-html,Python,Http,Python Requests,Python Requests Html,我知道requests.get()提供了一个HTTP接口,程序员可以向HTTP服务器发出各种请求 这告诉我必须在某个地方打开一个端口,以便请求能够发生 考虑到这一点,如果在响应/完成请求之前脚本被停止(例如,由于键盘中断,因此执行脚本的机器保持与internet的连接),会发生什么情况 端口/连接是否保持打开状态? 端口/连接是否自动关闭?问题的简短回答是:如果出现任何异常,包括键盘中断和系统退出,请求将关闭连接 对requests源代码的深入分析表明,requests.get最终调用了该方法(
requests.get()
提供了一个HTTP接口,程序员可以向HTTP服务器发出各种请求
这告诉我必须在某个地方打开一个端口,以便请求能够发生
考虑到这一点,如果在响应/完成请求之前脚本被停止(例如,由于键盘中断,因此执行脚本的机器保持与internet的连接),会发生什么情况
端口/连接是否保持打开状态?
端口/连接是否自动关闭?问题的简短回答是:如果出现任何异常,包括
键盘中断
和系统退出
,请求将关闭连接
对requests源代码的深入分析表明,requests.get
最终调用了该方法(这就是所有神奇之处)
在send
方法中发出请求有两种方式:分块或不分块。我们执行哪个发送
取决于请求的值。正文
和内容长度
标题:
chunked = not (request.body is None or 'Content-Length' in request.headers)
在请求主体为None
或设置了内容长度的情况下,请求将使用urllib3
的高级方法:
if not chunked:
resp = conn.urlopen(
method=request.method,
url=url,
body=request.body,
# ...
)
urllib3.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
在响应可以分块的情况下,请求的级别稍微低一点,并使用urllib3
提供的底层低级连接。在这种情况下,请求仍会处理异常,它会使用一个块来执行此操作,该块在获取连接后立即启动,并以以下方式结束:
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
有趣的是,如果没有错误,连接可能不会关闭,这取决于您为urlib3
配置连接池的方式。在成功执行的情况下,连接被放回连接池(尽管我在请求中找不到发送的源中的\u put\u conn
调用,这可能是分块工作流中的错误)。在低得多的级别上,当程序退出时,操作系统内核关闭该程序打开的所有文件描述符。这些包括网络插座。非常有趣。更有趣的是,正如公认的答案所说,如果没有错误,连接可能不会关闭。。。很高兴能探索一下。。。