我想“ping”服务器,检查 header 响应以查看链接是否断开,如果没有断开,则实际下载响应正文。
传统上,使用 sync 方法和 requests
模块,你可以发送一个 get
请求 stream = True
参数,并在响应主体下载之前捕获 header ,决定在出现错误(例如未找到)的情况下中止连接。
我的问题是,使用异步库 grequests
或 requests-futures
对我减少的知识库来说已经变得不可能了。
我已经尝试在 request-futures
中将流参数设置为 true 但没有用,它仍然会下载响应主体,而不会在它获得响应 header 时立即进行干预。即使是这样,我也不确定如何继续。
这是我试过的:
测试.py
from requests_futures.sessions import FuturesSession
session = FuturesSession()
session.stream = True
future = session.get('http://www.google.com')
response = future.result()
print(response.status_code) # Here I would assume the response body hasn't been loaded
调试后我发现它会以任何一种方式下载响应主体。
对于最初问题的任何解决方案,无论是否符合我的逻辑,我都将不胜感激。
最佳答案
我相信你想要的是一个 HTTP HEAD 请求:
session.head('http://www.google.com')
根据 w3.org , “HEAD 方法与 GET 相同,只是服务器不得在响应中返回消息体。”如果您喜欢状态代码和 header ,您可以跟进一个正常的 GET 请求。
对于评论,您似乎也有兴趣在单个请求中执行此操作。可以直接使用套接字这样做。发送正常的 GET 请求,对第一个 block 执行 recv,如果您不喜欢结果,请关闭连接,否则循环其余 block 。
这是一个关于如何通过单个请求有条件地下载的概念证明:
import socket
def fetch_on_header_condition(host, resource, condition, port=80):
request = 'GET %s HTTP/1.1\r\n' % resource
request += 'Host: %s\r\n' % host
request += 'Connection: close\r\n'
request += '\r\n'
s = socket.socket()
try:
s.connect((host, port))
s.send(request)
first_block = s.recv(4096)
if not condition(first_block):
return False, ''
blocks = [first_block]
while True:
block = s.recv(4096)
if not block:
break
blocks.append(block)
return True, ''.join(blocks)
finally:
s.close()
if __name__ == '__main__':
print fetch_on_header_condition(
host = 'www.jython.org',
port = 80,
resource = '/',
condition = lambda s: 'Content-Type: text/xml' in s,
)
关于python - 防止在 python 异步 http 请求中下载响应主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42966224/