我想“ping”服务器,检查标头响应以查看链接是否损坏,如果它不是损坏,实际下载响应正文。
传统上,将 sync 方法与requests
模块一起使用,您可以使用get
参数发送stream = True
请求,并在之前捕获标头响应正文下载,如果出现错误(例如找不到),则决定中止连接。
我的问题是,使用异步库grequests
或requests-futures
执行此操作对于我减少的知识库来说已经不可能了。
我已经尝试在request-futures
中将stream参数设置为true但是没有用,它仍会下载响应正文,而不会让我在获得响应标头后立即进行干预。即使它确实如此,我也不确定如何继续。
这是我尝试过的:
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
经过调试,我发现它会以任何一种方式下载响应体。
我很感激最初问题的任何解决方案,无论是否符合我的逻辑。
答案 0 :(得分:2)
我相信你想要的是HTTP HEAD请求:
session.head('http://www.google.com')
Per w3.org," HEAD方法与GET相同,只是服务器不能在响应中返回消息体。"如果您喜欢状态代码和标题,则可以使用正常的GET请求进行跟进。
对于评论,看起来您可能也有兴趣在单个请求中执行此操作。可以直接使用套接字进行此操作。发送正常的GET请求,执行第一个块的 recv ,如果您不喜欢结果,请关闭连接,否则循环其余块。
以下是有关如何通过单个请求有条件下载的概念证明:
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,
)
答案 1 :(得分:1)
只需检查头部请求中的状态,然后继续:
header = session.head('https://google.com')
if header.ok is True:
session.get('https://google.com')