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

时间:2017-03-23 02:34:41

标签: python http python-requests head grequests

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

传统上,将 sync 方法与requests模块一起使用,您可以使用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

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

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

2 个答案:

答案 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')