首页 > 其他分享 >修改grequests为返回响应结果和请求头

修改grequests为返回响应结果和请求头

时间:2023-03-06 23:34:17浏览次数:34  
标签:None 请求 grequests self request exception 响应 kwargs requests

保存以下文件为 grequests.py

# -*- coding: utf-8 -*-

"""
grequests
~~~~~~~~~

This module contains an asynchronous replica of ``requests.api``, powered
by gevent. All API methods return a ``Request`` instance (as opposed to
``Response``). A list of requests can be sent with ``map()``.
"""
from functools import partial
import traceback

try:
    import gevent
    from gevent import monkey as curious_george
    from gevent.pool import Pool
except ImportError:
    raise RuntimeError('Gevent is required for grequests.')

# Monkey-patch.
curious_george.patch_all(thread=False, select=False)

from requests import Session

__all__ = (
    'map', 'imap',
    'get', 'options', 'head', 'post', 'put', 'patch', 'delete', 'request'
)


class AsyncRequest(object):
    """ Asynchronous request.

    Accept same parameters as ``Session.request`` and some additional:

    :param session: Session which will do request
    :param callback: Callback called on response.
                     Same as passing ``hooks={'response': callback}``
    """
    def __init__(self, method, url, **kwargs):
        #: Request method
        self.method = method
        #: URL to request
        self.url = url
        #: Associated ``Session``
        self.session = kwargs.pop('session', None)
        if self.session is None:
            self.session = Session()
            self._close = True
        else:
            self._close = False  # don't close adapters after each request if the user provided the session

        callback = kwargs.pop('callback', None)
        if callback:
            kwargs['hooks'] = {'response': callback}

        #: The rest arguments for ``Session.request``
        self.kwargs = kwargs
        #: Resulting ``Response``
        self.response = None

    def send(self, **kwargs):
        """
        Prepares request based on parameter passed to constructor and optional ``kwargs```.
        Then sends request and saves response to :attr:`response`

        :returns: ``Response``
        """
        merged_kwargs = {}
        merged_kwargs.update(self.kwargs)
        merged_kwargs.update(kwargs)
        try:
            self.response = self.session.request(self.method,
                                                self.url, **merged_kwargs)
        except Exception as e:
            self.exception = e
            self.traceback = traceback.format_exc()
        finally:
            if self._close:
                # if we provided the session object, make sure we're cleaning up
                # because there's no sense in keeping it open at this point if it wont be reused
                self.session.close()
        return self


def send(r, pool=None, stream=False):
    """Sends the request object using the specified pool. If a pool isn't
    specified this method blocks. Pools are useful because you can specify size
    and can hence limit concurrency."""
    if pool is not None:
        return pool.spawn(r.send, stream=stream)

    return gevent.spawn(r.send, stream=stream)


# Shortcuts for creating AsyncRequest with appropriate HTTP method
get = partial(AsyncRequest, 'GET')
options = partial(AsyncRequest, 'OPTIONS')
head = partial(AsyncRequest, 'HEAD')
post = partial(AsyncRequest, 'POST')
put = partial(AsyncRequest, 'PUT')
patch = partial(AsyncRequest, 'PATCH')
delete = partial(AsyncRequest, 'DELETE')

# synonym
def request(method, url, **kwargs):
    return AsyncRequest(method, url, **kwargs)


def map(requests, stream=False, size=None, exception_handler=None, gtimeout=None):
    """Concurrently converts a list of Requests to Responses.

    :param requests: a collection of Request objects.
    :param stream: If True, the content will not be downloaded immediately.
    :param size: Specifies the number of requests to make at a time. If None, no throttling occurs.
    :param exception_handler: Callback function, called when exception occured. Params: Request, Exception
    :param gtimeout: Gevent joinall timeout in seconds. (Note: unrelated to requests timeout)
    """

    requests = list(requests)

    pool = Pool(size) if size else None
    jobs = [send(r, pool, stream=stream) for r in requests]
    gevent.joinall(jobs, timeout=gtimeout)

    ret = []

    for request in requests:
        if request.response is not None:
            ret.append([request.response,request])
        elif exception_handler and hasattr(request, 'exception'):
            ret.append([exception_handler(request, request.exception),request])
        elif exception_handler and not hasattr(request, 'exception'):
            ret.append([exception_handler(request, None),request])
        else:
            ret.append([None,None])

    return ret


def imap(requests, stream=False, size=2, exception_handler=None):
    """Concurrently converts a generator object of Requests to
    a generator of Responses.

    :param requests: a generator of Request objects.
    :param stream: If True, the content will not be downloaded immediately.
    :param size: Specifies the number of requests to make at a time. default is 2
    :param exception_handler: Callback function, called when exception occurred. Params: Request, Exception
    """

    pool = Pool(size)

    def send(r):
        return r.send(stream=stream)

    for request in pool.imap_unordered(send, requests):
        if request.response is not None:
            yield request.response
        elif exception_handler:
            ex_result = exception_handler(request, request.exception)
            if ex_result is not None:
                yield ex_result

    pool.join()

标签:None,请求,grequests,self,request,exception,响应,kwargs,requests
From: https://www.cnblogs.com/tiansz/p/17185930.html

相关文章

  • 了解HTTP请求和响应
    介绍HTTP(超文本传输协议)是一种用于Web服务器和客户端之间通信的协议。它是万维网上数据通信的基础。HTTP请求和响应是Web通信的重要组成部分,允许客户端向服务器请求资......
  • 统一日志输出打印POST请求参数
    众所周知,request.getInputStream()只能调一次。如果希望在请求进入Controller之前统一打印请求参数(拦截器或过滤器),又不影响业务,我们只能将获取到的输入流缓存起来,后续都从......
  • 获取struts请求参数的三种方式
    一、请求参数直接注入对应Action的属性中要求:(1)Action类必须为要接受参数的成员变量提供setXXX()方法;(2)jsp中表单的name属性须与Action中接受参数的成员变量的setter方法......
  • 怎么创建一个购物程序?这个响应式UI组件库不要错过!
    KendoUI致力于新的开发,来满足不断变化的需求。KendoUIforVue使用旨在提高性能和丰富用户体验的Vue组件,帮助开发人员构建下一代应用程序。它是为Vue技术框架提供可用的K......
  • 初识VUE响应式原理
    作者:京东零售吴静自从Vue发布以来,就受到了广大开发人员的青睐,提到Vue,我们首先想到的就是Vue的响应式系统,那响应式系统到底是怎么回事呢?接下来我就给大家简单介绍一下Vue......
  • .NET(C#) HttpClient单例(Singleton)和每次请求new HttpClient对比
    本文主要介绍.NET(C#)中,使用HttpClient执行求时,每次请求都执行newHttpClient创建一个实例和每次请求都使用同一个HttpClient(单例Singleton)分比区别。 1、每次请求创......
  • 实现一个批量请求函数, 能够限制并发量
    <!DOCTYPEhtml><htmllang="en"> <head>  <metacharset="UTF-8"/>  <metahttp-equiv="X-UA-Compatible"content="IE=edge"/>  <metaname="viewp......
  • 浙里办通用请求的封装
    开发浙里办应用都知道,我们发布到线上的接口需要按这样的方式去请求:但是往往本地开发的时候是连得公司测试环境,而且接口调用方式也不长这样。我第一次开发浙里办项目的时......
  • 百度、cnzz、piwik 统计ajax请求方法
    百度统计:<scripttype="text/javascript">$('area').click(function(){//目标urlvarbaiduStatUrl=$(this).attr('href').replace('http://','......
  • 已拦截跨源请求:同源策略禁止读取位于 http:// 的远程资源。(原因:CORS 头缺少 'Access-C
    这个报错提示是因为在同源策略下,JavaScript代码试图跨域访问另一个源(例如不同的域名、协议或端口)的资源,而服务器未设置CORS头部信息。同源策略是一个重要的安全特性,用于保......