当前位置: 首页 > 后端技术 > Python

求源码阅读-Day5

时间:2023-03-26 12:07:51 Python

求源码阅读-Day5求源码阅读-Day5Get方法RequestGet方法Session对象实例化后指向session,然后调用其内部方法request:从例子中分析:[jian@laptoprequests]$cattest.pyimportrequestsurl="http://www.baidu.com"resp=requests.get(url)然后去requests/__init__.py看Toimportthegetmethodinapi.pyfrom.apiimportrequest,get,head,post,patch,put,delete,options继续api.py找到get方法defget(url,params=None,**kwargs):r"""发送GET请求。:paramurl:新:class:`Request`对象的URL。:paramparams:(可选)字典、要发送的元组或字节列表在:class:`Request`的查询字符串中。:param\*\*kwargs:``request``采用的可选参数。:return::class:`Response`对象:rtype:requests.Response"""kwargs.setdefault('allow_redirects',True)返回请求uest('get',url,params=params,**kwargs)从request方法的注释可以看出,该方法的作用是构造Request对象,准备并发送,最后返回Response目的。Request我们来看看Request:defrequest(method,url,**kwargs):withsessions.Session()assession:returnsession.request(method=method,url=url,**kwargs)为什么这?Session对象具有保留参数的功能,支持持久化cookies和urllib3的连接池功能。当我们向同一个主机发送多个请求时,底层的TCP连接将被重用,这将带来显着的性能提升,同时也为我们节省了大量的工作,而且我们不必为每个请求都设置参数。但是并不是每个请求都需要保持长连接和retain参数,因为这样会带来资源释放失败的风险,所以在我们常规的方法中,引入了with语句来保证Session对象的正常退出。通过代码演示一下两个人的区域:>>>s=requests.session()>>>s.get("http://httpbin.org/cookies/set/sessioncookie/123456789")>>>r=s.get("http://httpbin.org/cookies")>>>print(r.text){"cookies":{"sessioncookie":"123456789"}}>>>请求。get("http://httpbin.org/cookies/set/sessioncookie/123456789")<响应[200]>>>>r=requests.get("http://httpbin.org/cookies")>>>print(r.text){"cookies":{}}着重看下session.request方法:sessions.pyclassSession(SessionRedirectMixin):...defrequest(self,method,url,...):...#创建请求。req=Request(method=method.upper(),url=url,headers=headers,files=files,data=dataor{},json=json,params=paramsor{},auth=auth,cookies=cookies,hooks=钩子,)prep=self.prepare_request(req)......继续研究Request,其实就是在models.py中导入Requestfrom.modelsimportRequest,PreparedRequest,DEFAULT_REDIRECT_LIMIT继续往models.py里面看Request(RequestHooksMixin):"""一个用户创建的:class:`Request`对象。用于准备一个:class:`PreparedRequest`,它被发送到服务器。..."""def__init__(self,method=None,url=None,headers=None,files=None,data=None,params=None,auth=None,cookies=None,hooks=None,json=None):...classRequest继承类RequestHooksMixin,classRequestHooksMixin提供了hooks事件注册和注销的接口方法初始化方法,实现了hooks事件注册,然后是一波参数设置。Request类对象是为后续类PreparedRequest对象的创建做准备。构造请求对象实例后,调用prepare_request方法:sessions.pyclassSession(SessionRedirectMixin):"""ARequestssession.Providescookiepersistence,connection-pooling,andconfiguration...."""...defprepare_request(self,request):"""构造一个:class:`PreparedRequest`用于传输并返回它。:class:`PreparedRequest`具有从:class:`Request`实例合并的设置,并且那些:class:`Session`。...prepare_request(self,request)方法的作用是构造一个PreparedRequest对象进行传输并返回。那么PreparedRequest对象是如何构造的呢?它是由Request组成的instance对象和Session对象中的数据(如cookies、stream、verify、proxies等)合并了,为什么参数分别放在Request对象和Session对象中呢?估计是和session参数持久化有关和连接池等,你可以充分利用之前请求存储的参数。PreparedRequest对图像构建完成后,最后再通过send方法将其发送出去:sessions.pyclassSession(SessionRedirectMixin):"""ARequestssession.Providescookiepersistence,connection-pooling,andconfiguration...."""...defrequest(self,method,url,...):"""构造一个:class:`Request`,准备并发送它。返回:class:`Response`对象。...:rtype:requests.Response"""...resp=self.send(prep,**send_kwargs)returnresp......defsend(self,request,**kwargs):"""发送一个givenPreparedRequest.:rtype:requests.Response"""...#获取合适的适配器使用adapter=self.get_adapter(url=request.url)...#发送请求r=adapter.send(request,**kwargs)...returnrsend方法:defsend(self,request,**kwargs):"""SendagivenPreparedRequest.:rtype:requests.Response"""#设置挂钩可以利用的默认值,以确保它们始终具有#正确的参数来重现先前的请求。kwargs.setdefault('stream',self.stream)kwargs.setdefault('verify',self.verify)kwargs.setdefault('cert',self.cert)kwargs.setdefault('proxies',self.proxies)#这是用户可能会不小心发送Request对象。#防范特定的失败案例。ifisinstance(request,Request):raiseValueError('YoucanonlysendPreparedRequests.')......send方法接收到PreparedRequest对象,然后获取对应的Transmissionadapter,这个transmissionadapter就是我们前面提到的HTTPAdapter.其底层由强大的urllib3库实现,提供了请求的所有HTTP和HTTPS接口方法,包括send等。当send方法向服务器发送请求后,等待服务器的响应,最后返回Response对象。这里涉及到NotImplementedError和generator的一些用法。到这里,一个完整的HTTP请求就完成了。总之:session.py是最大的难点,因为里面包含了很多东西