Skip to content

快速入门

¥QuickStart

首先,从导入 HTTPX 开始:

¥First, start by importing HTTPX:

>>> import httpx

现在,让我们尝试获取一个网页。

¥Now, let’s try to get a webpage.

>>> r = httpx.get('https://httpbin.org/get')
>>> r
<Response [200 OK]>

类似地,要发出 HTTP POST 请求:

¥Similarly, to make an HTTP POST request:

>>> r = httpx.post('https://httpbin.org/post', data={'key': 'value'})

PUT、DELETE、HEAD 和 OPTIONS 请求都遵循相同的样式:

¥The PUT, DELETE, HEAD, and OPTIONS requests all follow the same style:

>>> r = httpx.put('https://httpbin.org/put', data={'key': 'value'})
>>> r = httpx.delete('https://httpbin.org/delete')
>>> r = httpx.head('https://httpbin.org/get')
>>> r = httpx.options('https://httpbin.org/get')

在 URL 中传递参数

¥Passing Parameters in URLs

要在请求中包含 URL 查询参数,请使用params关键词:

¥To include URL query parameters in the request, use the params keyword:

>>> params = {'key1': 'value1', 'key2': 'value2'}
>>> r = httpx.get('https://httpbin.org/get', params=params)

要查看值如何编码到 URL 字符串中,我们可以检查用于发出请求的结果 URL:

¥To see how the values get encoding into the URL string, we can inspect the resulting URL that was used to make the request:

>>> r.url
URL('https://httpbin.org/get?key2=value2&key1=value1')

您还可以将项目列表作为值传递:

¥You can also pass a list of items as a value:

>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> r = httpx.get('https://httpbin.org/get', params=params)
>>> r.url
URL('https://httpbin.org/get?key1=value1&key2=value2&key2=value3')

响应内容

¥Response Content

HTTPX 将自动处理将响应内容解码为 Unicode 文本。

¥HTTPX will automatically handle decoding the response content into Unicode text.

>>> r = httpx.get('https://www.example.org/')
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'

您可以检查将使用什么编码来解码响应。

¥You can inspect what encoding will be used to decode the response.

>>> r.encoding
'UTF-8'

在某些情况下,响应可能不包含明确的编码,在这种情况下 HTTPX 将尝试自动确定要使用的编码。

¥In some cases the response may not contain an explicit encoding, in which case HTTPX will attempt to automatically determine an encoding to use.

>>> r.encoding
None
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'

如果您需要覆盖标准行为并明确设置要使用的编码,那么您也可以这样做。

¥If you need to override the standard behaviour and explicitly set the encoding to use, then you can do that too.

>>> r.encoding = 'ISO-8859-1'

二进制响应内容

¥Binary Response Content

对于非文本响应,响应内容也可以以字节形式访问:

¥The response content can also be accessed as bytes, for non-text responses:

>>> r.content
b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'

任何gzipdeflateHTTP 响应编码将自动为您解码。如果brotlipy安装后,brotli将支持响应编码。如果zstandard已安装,那么zstd响应编码也将得到支持。

¥Any gzip and deflate HTTP response encodings will automatically be decoded for you. If brotlipy is installed, then the brotli response encoding will be supported. If zstandard is installed, then zstd response encodings will also be supported.

例如,要从请求返回的二进制数据创建图像,可以使用以下代码:

¥For example, to create an image from binary data returned by a request, you can use the following code:

>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(r.content))

JSON 响应内容

¥JSON Response Content

Web API 响应通常会被编码为 JSON。

¥Often Web API responses will be encoded as JSON.

>>> r = httpx.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...' ...  }}]

自定义标题

¥Custom Headers

要在传出请求中包含其他标头,请使用headers关键字参数:

¥To include additional headers in the outgoing request, use the headers keyword argument:

>>> url = 'https://httpbin.org/headers'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = httpx.get(url, headers=headers)

发送表单编码数据

¥Sending Form Encoded Data

某些类型的 HTTP 请求,例如POSTPUT请求可以在请求体中包含数据。一种常见的包含方式是使用表单编码数据,用于 HTML 表单。

¥Some types of HTTP requests, such as POST and PUT requests, can include data in the request body. One common way of including that is as form-encoded data, which is used for HTML forms.

>>> data = {'key1': 'value1', 'key2': 'value2'}
>>> r = httpx.post("https://httpbin.org/post", data=data)
>>> print(r.text)
{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}

表单编码数据还可以包含来自给定键的多个值。

¥Form encoded data can also include multiple values from a given key.

>>> data = {'key1': ['value1', 'value2']}
>>> r = httpx.post("https://httpbin.org/post", data=data)
>>> print(r.text)
{
  ...
  "form": {
    "key1": [
      "value1",
      "value2"
    ]
  },
  ...
}

发送分段文件上传

¥Sending Multipart File Uploads

您还可以使用 HTTP 多部分编码上传文件:

¥You can also upload files, using HTTP multipart encoding:

>>> with open('report.xls', 'rb') as report_file:
...     files = {'upload-file': report_file}
...     r = httpx.post("https://httpbin.org/post", files=files)
>>> print(r.text)
{
  ...
  "files": {
    "upload-file": "<... binary content ...>"
  },
  ...
}

您还可以通过使用文件值的项目元组来明确设置文件名和内容类型:

¥You can also explicitly set the filename and content type, by using a tuple of items for the file value:

>>> with open('report.xls', 'rb') report_file:
...     files = {'upload-file': ('report.xls', report_file, 'application/vnd.ms-excel')}
...     r = httpx.post("https://httpbin.org/post", files=files)
>>> print(r.text)
{
  ...
  "files": {
    "upload-file": "<... binary content ...>"
  },
  ...
}

如果您需要在多部分表单中包含非文件数据字段,请使用data=...范围:

¥If you need to include non-file data fields in the multipart form, use the data=... parameter:

>>> data = {'message': 'Hello, world!'}
>>> with open('report.xls', 'rb') as report_file:
...     files = {'file': report_file}
...     r = httpx.post("https://httpbin.org/post", data=data, files=files)
>>> print(r.text)
{
  ...
  "files": {
    "file": "<... binary content ...>"
  },
  "form": {
    "message": "Hello, world!",
  },
  ...
}

发送 JSON 编码数据

¥Sending JSON Encoded Data

如果您只需要一个简单的键值数据结构,那么表单编码数据是可以的。对于更复杂的数据结构,您通常需要使用 JSON 编码。

¥Form encoded data is okay if all you need is a simple key-value data structure. For more complicated data structures you'll often want to use JSON encoding instead.

>>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']}
>>> r = httpx.post("https://httpbin.org/post", json=data)
>>> print(r.text)
{
  ...
  "json": {
    "boolean": true,
    "integer": 123,
    "list": [
      "a",
      "b",
      "c"
    ]
  },
  ...
}

发送二进制请求数据

¥Sending Binary Request Data

对于其他编码,您应该使用content=...参数,传递bytes类型或产生bytes

¥For other encodings, you should use the content=... parameter, passing either a bytes type or a generator that yields bytes.

>>> content = b'Hello, world'
>>> r = httpx.post("https://httpbin.org/post", content=content)

您可能还想设置自定义Content-Type上传二进制数据时的标头。

¥You may also want to set a custom Content-Type header when uploading binary data.

响应状态代码

¥Response Status Codes

我们可以检查响应的 HTTP 状态代码:

¥We can inspect the HTTP status code of the response:

>>> r = httpx.get('https://httpbin.org/get')
>>> r.status_code
200

HTTPX 还包含一个简单的快捷方式,可以通过文本短语访问状态代码。

¥HTTPX also includes an easy shortcut for accessing status codes by their text phrase.

>>> r.status_code == httpx.codes.OK
True

我们可以对任何不是 2xx 成功代码的响应引发异常:

¥We can raise an exception for any responses which are not a 2xx success code:

>>> not_found = httpx.get('https://httpbin.org/status/404')
>>> not_found.status_code
404
>>> not_found.raise_for_status()
Traceback (most recent call last):
  File "/Users/tomchristie/GitHub/encode/httpcore/httpx/models.py", line 837, in raise_for_status
    raise HTTPStatusError(message, response=self)
httpx._exceptions.HTTPStatusError: 404 Client Error: Not Found for url: https://httpbin.org/status/404
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404

任何成功的响应代码将返回Response实例而不是引发异常。

¥Any successful response codes will return the Response instance rather than raising an exception.

>>> r.raise_for_status()

该方法返回响应实例,允许你以内联方式使用它。例如:

¥The method returns the response instance, allowing you to use it inline. For example:

>>> r = httpx.get('...').raise_for_status()
>>> data = httpx.get('...').raise_for_status().json()

响应标头

¥Response Headers

响应头可作为类似字典的界面使用。

¥The response headers are available as a dictionary-like interface.

>>> r.headers
Headers({
    'content-encoding': 'gzip',
    'transfer-encoding': 'chunked',
    'connection': 'close',
    'server': 'nginx/1.0.4',
    'x-runtime': '148ms',
    'etag': '"e1ca502697e5c9317743dc078f67693f"',
    'content-type': 'application/json'
})

Headers数据类型不区分大小写,因此您可以使用任何大写字母。

¥The Headers data type is case-insensitive, so you can use any capitalization.

>>> r.headers['Content-Type']
'application/json'

>>> r.headers.get('content-type')
'application/json'

单个响应标头的多个值表示为单个逗号分隔的值,如RFC 7230

¥Multiple values for a single response header are represented as a single comma-separated value, as per RFC 7230:

接收者可以将多个具有相同字段名称的标头字段组合成一个“字段名称:字段值”对,而无需更改消息的语义,方法是按顺序将每个后续字段值附加到组合字段值,并用逗号分隔。

¥A recipient MAY combine multiple header fields with the same field name into one “field-name: field-value” pair, without changing the semantics of the message, by appending each subsequent field-value to the combined field value in order, separated by a comma.

流式响应

¥Streaming Responses

对于大型下载,您可能需要使用流式响应,而不会将整个响应主体一次加载到内存中。

¥For large downloads you may want to use streaming responses that do not load the entire response body into memory at once.

您可以流式传输响应的二进制内容......

¥You can stream the binary content of the response...

>>> with httpx.stream("GET", "https://www.example.com") as r:
...     for data in r.iter_bytes():
...         print(data)

或者回复的文本...

¥Or the text of the response...

>>> with httpx.stream("GET", "https://www.example.com") as r:
...     for text in r.iter_text():
...         print(text)

或者逐行传输文本...

¥Or stream the text, on a line-by-line basis...

>>> with httpx.stream("GET", "https://www.example.com") as r:
...     for line in r.iter_lines():
...         print(line)

HTTPX 将使用通用行尾,将所有情况标准化为\n

¥HTTPX will use universal line endings, normalising all cases to \n.

在某些情况下,你可能希望访问响应中的原始字节,而不应用任何 HTTP 内容解码。在这种情况下,Web 服务器应用的任何内容编码,例如gzipdeflatebrotli, 或者zstd将不会自动解码。

¥In some cases you might want to access the raw bytes on the response without applying any HTTP content decoding. In this case any content encoding that the web server has applied such as gzip, deflate, brotli, or zstd will not be automatically decoded.

>>> with httpx.stream("GET", "https://www.example.com") as r:
...     for chunk in r.iter_raw():
...         print(chunk)

如果你以任何一种方式使用流式响应,那么response.contentresponse.text属性将不可用,并且访问时会引发错误。但是,您也可以使用响应流功能有条件地加载响应主体:

¥If you're using streaming responses in any of these ways then the response.content and response.text attributes will not be available, and will raise errors if accessed. However you can also use the response streaming functionality to conditionally load the response body:

>>> with httpx.stream("GET", "https://www.example.com") as r:
...     if int(r.headers['Content-Length']) < TOO_LONG:
...         r.read()
...         print(r.text)

曲奇饼

¥Cookies

可以轻松访问在响应中设置的任何 cookie:

¥Any cookies that are set on the response can be easily accessed:

>>> r = httpx.get('https://httpbin.org/cookies/set?chocolate=chip')
>>> r.cookies['chocolate']
'chip'

要在传出请求中包含 Cookie,请使用cookies范围:

¥To include cookies in an outgoing request, use the cookies parameter:

>>> cookies = {"peanut": "butter"}
>>> r = httpx.get('https://httpbin.org/cookies', cookies=cookies)
>>> r.json()
{'cookies': {'peanut': 'butter'}}

Cookies 返回Cookies实例,它是一个类似字典的数据结构,带有用于通过域或路径访问 cookie 的附加 API。

¥Cookies are returned in a Cookies instance, which is a dict-like data structure with additional API for accessing cookies by their domain or path.

>>> cookies = httpx.Cookies()
>>> cookies.set('cookie_on_domain', 'hello, there!', domain='httpbin.org')
>>> cookies.set('cookie_off_domain', 'nope.', domain='example.org')
>>> r = httpx.get('http://httpbin.org/cookies', cookies=cookies)
>>> r.json()
{'cookies': {'cookie_on_domain': 'hello, there!'}}

重定向和历史记录

¥Redirection and History

默认情况下,HTTPX 将不是遵循所有 HTTP 方法的重定向,尽管可以明确启用此功能。

¥By default, HTTPX will not follow redirects for all HTTP methods, although this can be explicitly enabled.

例如,GitHub 将所有 HTTP 请求重定向到 HTTPS。

¥For example, GitHub redirects all HTTP requests to HTTPS.

>>> r = httpx.get('http://github.com/')
>>> r.status_code
301
>>> r.history
[]
>>> r.next_request
<Request('GET', 'https://github.com/')>

您可以使用follow_redirects范围:

¥You can modify the default redirection handling with the follow_redirects parameter:

>>> r = httpx.get('http://github.com/', follow_redirects=True)
>>> r.url
URL('https://github.com/')
>>> r.status_code
200
>>> r.history
[<Response [301 Moved Permanently]>]

history响应的属性可用于检查所有后续的重定向。它包含所有已遵循的重定向响应的列表,按其生成的顺序排列。

¥The history property of the response can be used to inspect any followed redirects. It contains a list of any redirect responses that were followed, in the order in which they were made.

超时

¥Timeouts

HTTPX 默认为所有网络操作包含合理的超时,这意味着如果连接未正确建立,则它应该始终引发错误而不是无限期挂起。

¥HTTPX defaults to including reasonable timeouts for all network operations, meaning that if a connection is not properly established then it should always raise an error rather than hanging indefinitely.

网络不活动超时的默认时间为 5 秒。您可以修改该值,使其更严格或更宽松:

¥The default timeout for network inactivity is five seconds. You can modify the value to be more or less strict:

>>> httpx.get('https://github.com/', timeout=0.001)

您还可以完全禁用超时行为...

¥You can also disable the timeout behavior completely...

>>> httpx.get('https://github.com/', timeout=None)

对于高级超时管理,请参阅超时微调

¥For advanced timeout management, see Timeout fine-tuning.

验证

¥Authentication

HTTPX 支持基本和摘要式 HTTP 身份验证。

¥HTTPX supports Basic and Digest HTTP authentication.

要提供基本身份验证凭据,请传递 2 元组的纯文本str或者bytes对象作为auth请求函数的参数:

¥To provide Basic authentication credentials, pass a 2-tuple of plaintext str or bytes objects as the auth argument to the request functions:

>>> httpx.get("https://example.com", auth=("my_user", "password123"))

要提供摘要式身份验证的凭证,您需要实例化一个DigestAuth以明文用户名和密码作为参数的对象。然后可以将此对象作为auth请求方法的参数如上所述:

¥To provide credentials for Digest authentication you'll need to instantiate a DigestAuth object with the plaintext username and password as arguments. This object can be then passed as the auth argument to the request methods as above:

>>> auth = httpx.DigestAuth("my_user", "password123")
>>> httpx.get("https://example.com", auth=auth)
<Response [200 OK]>

例外

¥Exceptions

如果发生错误,HTTPX 将引发异常。

¥HTTPX will raise exceptions if an error occurs.

HTTPX 中最重要的异常类是RequestErrorHTTPStatusError

¥The most important exception classes in HTTPX are RequestError and HTTPStatusError.

RequestError类是超类,它包含发出 HTTP 请求时发生的任何异常。这些异常包括.request属性。

¥The RequestError class is a superclass that encompasses any exception that occurs while issuing an HTTP request. These exceptions include a .request attribute.

try:
    response = httpx.get("https://www.example.com/")
except httpx.RequestError as exc:
    print(f"An error occurred while requesting {exc.request.url!r}.")

HTTPStatusError班级由response.raise_for_status()对于非 2xx 成功代码的响应。这些例外包括.request和一个.response属性。

¥The HTTPStatusError class is raised by response.raise_for_status() on responses which are not a 2xx success code. These exceptions include both a .request and a .response attribute.

response = httpx.get("https://www.example.com/")
try:
    response.raise_for_status()
except httpx.HTTPStatusError as exc:
    print(f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.")

还有一个基类HTTPError包括这两个类别,并且可以用来捕获失败的请求或 4xx 和 5xx 响应。

¥There is also a base class HTTPError that includes both of these categories, and can be used to catch either failed requests, or 4xx and 5xx responses.

您可以使用这个基类来捕获这两个类别......

¥You can either use this base class to catch both categories...

try:
    response = httpx.get("https://www.example.com/")
    response.raise_for_status()
except httpx.HTTPError as exc:
    print(f"Error while requesting {exc.request.url!r}.")

或者明确处理每个案例......

¥Or handle each case explicitly...

try:
    response = httpx.get("https://www.example.com/")
    response.raise_for_status()
except httpx.RequestError as exc:
    print(f"An error occurred while requesting {exc.request.url!r}.")
except httpx.HTTPStatusError as exc:
    print(f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.")

有关可用例外的完整列表,请参阅异常(API 参考)

¥For a full list of available exceptions, see Exceptions (API Reference).