|
| 1 | +## httplib |
| 2 | + |
| 3 | +不推荐用 urllib 和 urllib2 ,最好用 requests,否则就用 httplib, httplib 是 urllib 和 urllib2 的底层库,但是使用起来和 requests 一样简单。 |
| 4 | + |
| 5 | +urllib 使用的是 httplib.HTTP, urllib2 使用的是 httplib.HTTPConnection |
| 6 | + |
| 7 | +根据历史的发展,我们知道用 HTTPConnection 应该是对的。然后阅读源码,证明我们的结论,HTTP 只是为了兼容历史版本,而且也改成了使用 HTTPConnection 的方式。 |
| 8 | + |
| 9 | +httplib 在 python3 中被换了个位置,变成了 http.client ,所有的引入方式从 `from httplib import **` 变成 `from http.client import **` 即可 |
| 10 | + |
| 11 | +为了让 python2 与 python3 兼容,在 python2 中也可以用 `http.client` 引入 httplib |
| 12 | + |
| 13 | +### HTTP |
| 14 | + |
| 15 | +httplib 作为一个基础库,首先定义了一些 HTTP 的常用枚举,包括 HTTP 的状态码和对应的解释说明。 |
| 16 | + |
| 17 | +``` |
| 18 | +# status codes |
| 19 | +# informational |
| 20 | +CONTINUE = 100 |
| 21 | +SWITCHING_PROTOCOLS = 101 |
| 22 | +PROCESSING = 102 |
| 23 | + |
| 24 | +# successful |
| 25 | +OK = 200 |
| 26 | +CREATED = 201 |
| 27 | +ACCEPTED = 202 |
| 28 | +NON_AUTHORITATIVE_INFORMATION = 203 |
| 29 | +NO_CONTENT = 204 |
| 30 | +RESET_CONTENT = 205 |
| 31 | +PARTIAL_CONTENT = 206 |
| 32 | +MULTI_STATUS = 207 |
| 33 | +IM_USED = 226 |
| 34 | + |
| 35 | +# redirection |
| 36 | +MULTIPLE_CHOICES = 300 |
| 37 | +MOVED_PERMANENTLY = 301 |
| 38 | +FOUND = 302 |
| 39 | +SEE_OTHER = 303 |
| 40 | +NOT_MODIFIED = 304 |
| 41 | +USE_PROXY = 305 |
| 42 | +TEMPORARY_REDIRECT = 307 |
| 43 | + |
| 44 | +# client error |
| 45 | +BAD_REQUEST = 400 |
| 46 | +UNAUTHORIZED = 401 |
| 47 | +PAYMENT_REQUIRED = 402 |
| 48 | +FORBIDDEN = 403 |
| 49 | +NOT_FOUND = 404 |
| 50 | +METHOD_NOT_ALLOWED = 405 |
| 51 | +NOT_ACCEPTABLE = 406 |
| 52 | +PROXY_AUTHENTICATION_REQUIRED = 407 |
| 53 | +REQUEST_TIMEOUT = 408 |
| 54 | +CONFLICT = 409 |
| 55 | +GONE = 410 |
| 56 | +LENGTH_REQUIRED = 411 |
| 57 | +PRECONDITION_FAILED = 412 |
| 58 | +REQUEST_ENTITY_TOO_LARGE = 413 |
| 59 | +REQUEST_URI_TOO_LONG = 414 |
| 60 | +UNSUPPORTED_MEDIA_TYPE = 415 |
| 61 | +REQUESTED_RANGE_NOT_SATISFIABLE = 416 |
| 62 | +EXPECTATION_FAILED = 417 |
| 63 | +UNPROCESSABLE_ENTITY = 422 |
| 64 | +LOCKED = 423 |
| 65 | +FAILED_DEPENDENCY = 424 |
| 66 | +UPGRADE_REQUIRED = 426 |
| 67 | + |
| 68 | +# server error |
| 69 | +INTERNAL_SERVER_ERROR = 500 |
| 70 | +NOT_IMPLEMENTED = 501 |
| 71 | +BAD_GATEWAY = 502 |
| 72 | +SERVICE_UNAVAILABLE = 503 |
| 73 | +GATEWAY_TIMEOUT = 504 |
| 74 | +HTTP_VERSION_NOT_SUPPORTED = 505 |
| 75 | +INSUFFICIENT_STORAGE = 507 |
| 76 | +NOT_EXTENDED = 510 |
| 77 | + |
| 78 | +# Mapping status codes to official W3C names |
| 79 | +responses = { |
| 80 | + 100: 'Continue', |
| 81 | + 101: 'Switching Protocols', |
| 82 | + |
| 83 | + 200: 'OK', |
| 84 | + 201: 'Created', |
| 85 | + 202: 'Accepted', |
| 86 | + 203: 'Non-Authoritative Information', |
| 87 | + 204: 'No Content', |
| 88 | + 205: 'Reset Content', |
| 89 | + 206: 'Partial Content', |
| 90 | + |
| 91 | + 300: 'Multiple Choices', |
| 92 | + 301: 'Moved Permanently', |
| 93 | + 302: 'Found', |
| 94 | + 303: 'See Other', |
| 95 | + 304: 'Not Modified', |
| 96 | + 305: 'Use Proxy', |
| 97 | + 306: '(Unused)', |
| 98 | + 307: 'Temporary Redirect', |
| 99 | + |
| 100 | + 400: 'Bad Request', |
| 101 | + 401: 'Unauthorized', |
| 102 | + 402: 'Payment Required', |
| 103 | + 403: 'Forbidden', |
| 104 | + 404: 'Not Found', |
| 105 | + 405: 'Method Not Allowed', |
| 106 | + 406: 'Not Acceptable', |
| 107 | + 407: 'Proxy Authentication Required', |
| 108 | + 408: 'Request Timeout', |
| 109 | + 409: 'Conflict', |
| 110 | + 410: 'Gone', |
| 111 | + 411: 'Length Required', |
| 112 | + 412: 'Precondition Failed', |
| 113 | + 413: 'Request Entity Too Large', |
| 114 | + 414: 'Request-URI Too Long', |
| 115 | + 415: 'Unsupported Media Type', |
| 116 | + 416: 'Requested Range Not Satisfiable', |
| 117 | + 417: 'Expectation Failed', |
| 118 | + |
| 119 | + 500: 'Internal Server Error', |
| 120 | + 501: 'Not Implemented', |
| 121 | + 502: 'Bad Gateway', |
| 122 | + 503: 'Service Unavailable', |
| 123 | + 504: 'Gateway Timeout', |
| 124 | + 505: 'HTTP Version Not Supported', |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +### 请求 |
| 129 | + |
| 130 | +httplib 中最重要的两个类 `HTTPConnection` 和 `HTTPSConnection` 分别对应 HTTP 请求和 HTTPS 请求。 |
| 131 | + |
| 132 | +可以先看下请求过程,在源代码注释中为我们画了这样一幅图。 |
| 133 | + |
| 134 | +``` |
| 135 | + (null) |
| 136 | + | |
| 137 | + | HTTPConnection() |
| 138 | + v |
| 139 | + Idle |
| 140 | + | |
| 141 | + | putrequest() |
| 142 | + v |
| 143 | + Request-started |
| 144 | + | |
| 145 | + | ( putheader() )* endheaders() |
| 146 | + v |
| 147 | + Request-sent |
| 148 | + | |
| 149 | + | response = getresponse() |
| 150 | + v |
| 151 | + Unread-response [Response-headers-read] |
| 152 | + |\____________________ |
| 153 | + | | |
| 154 | + | response.read() | putrequest() |
| 155 | + v v |
| 156 | + Idle Req-started-unread-response |
| 157 | + ______/| |
| 158 | + / | |
| 159 | + response.read() | | ( putheader() )* endheaders() |
| 160 | + v v |
| 161 | + Request-started Req-sent-unread-response |
| 162 | + | |
| 163 | + | response.read() |
| 164 | + v |
| 165 | + Request-sent |
| 166 | +``` |
| 167 | + |
| 168 | +发起 HTTP 请求 |
| 169 | + |
| 170 | +``` |
| 171 | +# -*- coding: utf-8 -*- |
| 172 | + |
| 173 | +import httplib |
| 174 | + |
| 175 | +connection = httplib.HTTPConnection("httpbin.org") |
| 176 | +# 打开日志 |
| 177 | +connection.set_debuglevel(1) |
| 178 | + |
| 179 | +# GET 请求 |
| 180 | +connection.request("GET", "/get?name=windard") |
| 181 | +response = connection.getresponse() |
| 182 | +print "HTTP GET:", response.read() |
| 183 | + |
| 184 | +# POST 请求 |
| 185 | +connection.request("POST", "/post", '{"haha":"lala"}', { |
| 186 | + "From": "China", |
| 187 | + "To": "USA", |
| 188 | + "Content-Type": "application/json", |
| 189 | +}) |
| 190 | + |
| 191 | +response = connection.getresponse() |
| 192 | +print "HTTP Status Code:", response.status |
| 193 | +print "HTTP Version:", response.version |
| 194 | +print "HTTP Reason:", response.reason |
| 195 | +print "HTTP headers:" |
| 196 | +print response.getheaders() |
| 197 | + |
| 198 | +print "HTTP Connection:", response.getheader("Connection") |
| 199 | +print "HTTP msg:", response.msg |
| 200 | + |
| 201 | +print "HTTP Body:", response.read() |
| 202 | + |
| 203 | +# 关闭连接 |
| 204 | +connection.close() |
| 205 | +``` |
| 206 | + |
| 207 | +使用 HTTPConnection 可以自己手动设置发送请求方式,请求头,请求参数,请求体,比较自由。 |
| 208 | + |
0 commit comments