防止python异步http请求中的响应正文下载

问题描述 投票:6回答:2

我想“ping”服务器,检查标头响应以查看链接是否损坏,如果没有损坏,实际下载响应正文。

传统上,使用requests模块的sync方法,您可以使用get参数发送stream = True请求,并在响应主体下载之前捕获标头,在出现错误(例如,未找到)时决定中止连接。

我的问题是,使用异步库grequestsrequests-futures执行此操作对于我减少的知识库来说已经不可能了。

我已经尝试在request-futures中将stream参数设置为true但是没有用,它仍会下载响应正文,而不会让我在获得响应标头后立即进行干预。即使它确实如此,我也不确定如何继续。

这就是我尝试过的:

test.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

经过调试,我发现它以任何一种方式下载响应体。

我会很感激最初问题的任何解决方案,无论它是否符合我的逻辑。

python http python-requests head grequests
2个回答
2
投票

我相信你想要的是一个HTTP HEAD请求:

session.head('http://www.google.com')

根据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
投票

只需检查头部请求中的状态并继续:

header = session.head('https://google.com')

if header.ok is True:
    session.get('https://google.com')
© www.soinside.com 2019 - 2024. All rights reserved.