{"id":7683,"date":"2021-10-04T10:14:09","date_gmt":"2021-10-04T02:14:09","guid":{"rendered":"https:\/\/kyle.ai\/blog\/?p=7683"},"modified":"2021-10-04T10:14:09","modified_gmt":"2021-10-04T02:14:09","slug":"python-%e8%af%b7%e6%b1%82-http-%e6%97%b6%e5%a6%82%e4%bd%95%e5%8e%bb%e6%8e%89-user-agent","status":"publish","type":"post","link":"https:\/\/kyle.ai\/blog\/7683.html","title":{"rendered":"Python \u8bf7\u6c42 HTTP \u65f6\u5982\u4f55\u53bb\u6389 User-Agent"},"content":{"rendered":"<p>\u4e0d\u7ba1\u662f\u4f7f\u7528 urllib3 \u6216\u662f\u7b2c\u4e09\u65b9\u5e93 requests\uff0c\u59cb\u7ec8\u65e0\u6cd5\u5b8c\u5168\u53bb\u6389\u4e24\u4e2a\u5934\u90e8\uff0c\u4e00\u4e2a\u662f User-Agent\uff0c\u4e00\u4e2a\u662f Accept-Encoding\uff0c\u8fd9\u662f\u5728 python \u7684\u5e95\u5c42\u5e93\u91cc\u9762\uff0c\u68c0\u6d4b\u5230\u6ca1\u6709\u8fd9\u4e24\u5934\u90e8\u65f6\u4f1a\u81ea\u52a8\u6dfb\u52a0\u4e0a\u53bb\u3002<\/p>\n<p>\u8981\u60f3\u53bb\u6389\uff0c\u53ef\u4ee5\u4fee\u6539\u5e95\u5c42\u5e93\uff0c\u505a\u4e00\u4e2a monkey patch\uff0c\u4fee\u6539\u6b64\u884c\u4e3a\u6240\u5728\u7684\u4ee3\u7801\u6587\u4ef6 <code>http.client.HTTPConnection._send_request<\/code> \uff0c\u4ee3\u7801\u5982\u4e0b<\/p>\n<pre><code class=\"language-python \">import http.client\n\ndef _send_request(self, method, url, body, headers, encode_chunked):\n    # Honor explicitly requested Host: and Accept-Encoding: headers.\n    header_names = frozenset(k.lower() for k in headers)\n    skips = {}\n    if 'host' in header_names:\n        skips['skip_host'] = 1\n    if True:  # \u53bb\u6389  accept_encoding  \u5934\u90e8\n        skips['skip_accept_encoding'] = 1\n\n    self.putrequest(method, url, **skips)\n\n    # chunked encoding will happen if HTTP\/1.1 is used and either\n    # the caller passes encode_chunked=True or the following\n    # conditions hold:\n    # 1. content-length has not been explicitly set\n    # 2. the body is a file or iterable, but not a str or bytes-like\n    # 3. Transfer-Encoding has NOT been explicitly set by the caller\n\n    if 'content-length' not in header_names:\n        # only chunk body if not explicitly set for backwards\n        # compatibility, assuming the client code is already handling the\n        # chunking\n        if 'transfer-encoding' not in header_names:\n            # if content-length cannot be automatically determined, fall\n            # back to chunked encoding\n            encode_chunked = False\n            content_length = self._get_content_length(body, method)\n            if content_length is None:\n                if body is not None:\n                    if self.debuglevel &gt; 0:\n                        print('Unable to determine size of %r' % body)\n                    encode_chunked = True\n                    self.putheader('Transfer-Encoding', 'chunked')\n            else:\n                self.putheader('Content-Length', str(content_length))\n    else:\n        encode_chunked = False\n    excluded_headers = ['User-Agent']  # \u9700\u8981\u53bb\u6389\u7684 header \u5934\n    # headers\n    for hdr, value in headers.items():\n        if hdr not in excluded_headers:\n            self.putheader(hdr, value)\n    if isinstance(body, str):\n        # RFC 2616 Section 3.7.1 says that text default has a\n        # default charset of iso-8859-1.\n        body = http.client._encode(body, 'body')\n    self.endheaders(body, encode_chunked=encode_chunked)\n\n\n# \u89e3\u51b3\u53d1\u9001 http \u8bf7\u6c42\u81ea\u52a8\u5e26 User-Agent \u548c Accept-Encoding \u5934\u7684\u95ee\u9898\nhttp.client.HTTPConnection._send_request = _send_request\n\n<\/code><\/pre>\n<p>\u4e0a\u9762\u6709\u4e2d\u6587\u6ce8\u91ca\u7684\u4e24\u5904\u5730\u65b9\uff0c\u5c31\u662f\u6211\u4eec\u4fee\u6539\u7684\u70b9\u3002\u4e00\u4e2a\u662f\u8bbe\u7f6e skip_accept_encoding\uff0c\u4e00\u4e2a\u662f\u6dfb\u52a0 excluded_headers \u5224\u65ad\u3002<\/p>\n<p>\u5728\u4f7f\u7528 requests \u524d\uff0c\u8c03\u7528\u4ee5\u4e0a\u4ee3\u7801 patch\uff0c\u518d\u50cf\u6b63\u5e38\u4e00\u6837\u4f7f\u7528\u5373\u53ef<\/p>\n<pre><code class=\"language-python \">session = requests.Session()\nsession.headers = {}\nreq = requests.Request('POST', url, data=data)\nprepped = req.prepare()\nprint(prepped.headers)\nres = session.send(prepped)\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4e0d\u7ba1\u662f\u4f7f\u7528 urllib3 \u6216\u662f\u7b2c\u4e09\u65b9\u5e93 requests\uff0c\u59cb\u7ec8\u65e0\u6cd5\u5b8c\u5168\u53bb\u6389\u4e24\u4e2a\u5934\u90e8\uff0c\u4e00\u4e2a\u662f User-Age [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-7683","post","type-post","status-publish","format-standard","hentry","category-code_related"],"_links":{"self":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/7683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/comments?post=7683"}],"version-history":[{"count":1,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/7683\/revisions"}],"predecessor-version":[{"id":7684,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/7683\/revisions\/7684"}],"wp:attachment":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/media?parent=7683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/categories?post=7683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/tags?post=7683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}