🔸 第一部分:requests库的入口
我们从requests
库的入口开始,通常我们会使用 requests.get()
或 requests.post()
等方法发送HTTP请求。那么,这些方法背后究竟做了些什么呢?我们从requests.get()
方法开始看起:
# requests/__init__.py def get(url, params=None, **kwargs): """Sends a GET request.""" return request('get', url, params=params, **kwargs)
🔹 requests.get()
实际上是调用了内部的 request()
方法,并将 'get'
作为请求方法传入。让我们进一步深入 request()
方法。
🔸 第二部分:request方法揭秘
在requests
库中,request()
方法负责构建和发送所有类型的HTTP请求:
# requests/api.py def request(method, url, **kwargs): session = sessions.Session() return session.request(method=method, url=url, **kwargs)
🔹 request()
方法创建了一个 Session
对象,然后调用了 session.request()
。这意味着实际的请求处理是由 Session
对象完成的。
🔸 第三部分:Session对象的奥秘
Session
对象在requests
库中扮演了重要角色。它不仅可以发送请求,还能保存cookie等会话信息:
# requests/sessions.py class Session(SessionRedirectMixin, RequestHookMixin): def request(self, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, proxies=None, hooks=None, stream=None, verify=True, cert=None, json=None): prep = self.prepare_request(Request(method=method, url=url, headers=headers, files=files, data=data, json=json, params=params, auth=auth, cookies=cookies, hooks=hooks)) ... send_kwargs = {'timeout': timeout, 'allow_redirects': allow_redirects, 'proxies': proxies, 'stream': stream, 'verify': verify, 'cert': cert, 'hooks': hooks} ... resp = self.send(prep, **send_kwargs) return resp
🔹 Session
对象的 request()
方法中首先调用 prepare_request()
方法来构建 Request
对象。然后调用 send()
方法来发送请求。
🔸 第四部分:Request对象的构建
prepare_request()
方法负责构建一个 Request
对象:
# requests/sessions.py def prepare_request(self, request): p = PreparedRequest() p.prepare( method=request.method.upper(), url=request.url, files=request.files, data=request.data, json=request.json, headers=request.headers, params=request.params, auth=request.auth, cookies=request.cookies, hooks=request.hooks, ) return p
🔹 prepare_request()
方法中调用了 PreparedRequest
类,并通过其 prepare()
方法将请求的各个部分准备好。
🔸 第五部分:PreparedRequest的准备
PreparedRequest
类是用来标准化和准备请求数据的:
# requests/models.py class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): def prepare(self, method=None, url=None, headers=None, files=None, data=None, params=None, auth=None, cookies=None, hooks=None, json=None): self.prepare_method(method) self.prepare_url(url, params) self.prepare_headers(headers) self.prepare_body(data, files, json) self.prepare_auth(auth, url) self.prepare_cookies(cookies) self.prepare_hooks(hooks)
🔹 PreparedRequest
类的 prepare()
方法中,分别调用了一系列 prepare_*
方法来准备HTTP请求的各个部分,如方法、URL、头信息、请求体等。
🔸 第六部分:发送请求
当请求准备好后,Session
对象的 send()
方法负责实际发送HTTP请求:
# requests/sessions.py def send(self, request, **kwargs): ... r = adapter.send(request, **kwargs) ... return r
🔹 send()
方法中最重要的一步是调用 adapter.send()
方法,这里的 adapter
是 HTTPAdapter
对象,它负责底层的HTTP请求发送。
🔸 第七部分:HTTPAdapter的发送
HTTPAdapter
对象的 send()
方法通过底层库(如urllib3
)来实际发送请求:
# requests/adapters.py class HTTPAdapter(BaseAdapter): def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): conn = self.get_connection(request.url, proxies) ... resp = conn.urlopen( method=request.method, url=request.url, body=request.body, headers=request.headers, ... ) return self.build_response(request, resp)
🔹 send()
方法通过 get_connection()
方法获取一个连接,然后使用 conn.urlopen()
发送请求,并调用 build_response()
方法构建响应对象。
🔸 第八部分:构建响应
build_response()
方法负责将底层响应对象转换为 requests
的 Response
对象:
# requests/adapters.py def build_response(self, request, resp): response = Response() response.status_code = resp.status response.headers = CaseInsensitiveDict(resp.headers) response.raw = resp response.url = request.url response.request = request response.connection = self return response
🔹 build_response()
方法中,将底层响应对象的状态码、头信息、URL等信息赋值给 Response
对象,从而完成响应构建。
🔸 总结
🔹 通过以上解析,我们了解了 requests
库从发送请求到接收响应的全过程。从 requests.get()
方法开始,经过 Session
对象的处理、PreparedRequest
的准备、HTTPAdapter
的发送,最终构建 Response
对象。这一系列流程确保了 requests
库能够简洁、高效地处理HTTP请求,让开发者可以专注于业务逻辑的实现。
希望通过这次源码解析,大家对 requests
库有了更深入的理解,能够更好地运用它进行网络请求处理! 🚀