python 请求kv库_Python的请求库(指南)

python 请求kv库

The requests library is the de facto standard for making HTTP requests in Python. It abstracts the complexities of making requests behind a beautiful, simple API so that you can focus on interacting with services and consuming data in your application.

requests库是在Python中发出HTTP请求的事实上的标准。 它通过漂亮,简单的API提取了发出请求的复杂性,因此您可以专注于与服务进行交互以及在应用程序中使用数据。

Throughout this article, you’ll see some of the most useful features that requests has to offer as well as how to customize and optimize those features for different situations you may come across. You’ll also learn how to use requests in an efficient way as well as how to prevent requests to external services from slowing down your application.

在本文中,您将看到requests所必须提供的一些最有用的功能,以及如何针对可能遇到的不同情况自定义和优化这些功能。 您还将学习如何高效地使用requests ,以及如何防止对外部服务的请求减慢您的应用程序的速度。

In this tutorial, you’ll learn how to:

在本教程中,您将学习如何:

  • Make requests using the most common HTTP methods
  • Customize your requests’ headers and data, using the query string and message body
  • Inspect data from your requests and responses
  • Make authenticated requests
  • Configure your requests to help prevent your application from backing up or slowing down
  • 使用最常见的HTTP方法发出请求
  • 使用查询字符串和消息正文来自定义请求的标题和数据
  • 检查您的请求和响应中的数据
  • 发出验证请求
  • 配置您的请求以帮助防止您的应用程序备份或减慢速度

Though I’ve tried to include as much information as you need to understand the features and examples included in this article, I do assume a very basic general knowledge of HTTP. That said, you still may be able to follow along fine anyway.

尽管我尝试提供尽可能多的信息以理解本文中包含的功能和示例,但是我确实假定了HTTP的非常基本的常识 。 也就是说,无论如何,您仍然可以继续进行。

Now that that is out of the way, let’s dive in and see how you can use requests in your application!

既然这已成问题,那么让我们深入研究一下如何在应用程序中使用requests

requests入门 (Getting Started With requests)

Let’s begin by installing the requests library. To do so, run the following command:

让我们从安装requests库开始。 为此,请运行以下命令:

 $ pip install requests
$ pip install requests

If you prefer to use Pipenv for managing Python packages, you can run the following:

如果您希望使用Pipenv来管理Python软件包,则可以运行以下命令:

Once requests is installed, you can use it in your application. Importing requests looks like this:

安装requests ,您可以在应用程序中使用它。 导入requests如下所示:

 import import requests
requests

Now that you’re all set up, it’s time to begin your journey through requests. Your first goal will be learning how to make a GET request.

现在您已经完成了所有的准备工作,该开始通过requests进行旅程了。 您的第一个目标是学习如何发出GET请求。

GET请求 (The GET Request)

HTTP methods such as GET and POST, determine which action you’re trying to perform when making an HTTP request. Besides GET and POST, there are several other common methods that you’ll use later in this tutorial.

HTTP方法(例如GETPOST )确定发出HTTP请求时要尝试执行的操作。 除了GETPOST之外,您还将在本教程的稍后部分中使用其他几种常用方法。

One of the most common HTTP methods is GET. The GET method indicates that you’re trying to get or retrieve data from a specified resource. To make a GET request, invoke requests.get().

GET是最常见的HTTP方法之一。 GET方法表示您正在尝试从指定资源获取或检索数据。 要发出GET请求,请调用requests.get()

To test this out, you can make a GET request to GitHub’s Root REST API by calling get() with the following URL:

为了进行测试,您可以通过使用以下URL调用get()来向GitHub的Root REST API发出GET请求:

>>>
>>>
 >>>  requests . get ( 'https://api.github.com' )
<Response [200]>

Congratulations! You’ve made your first request. Let’s dive a little deeper into the response of that request.

恭喜你! 您已经提出了第一个请求。 让我们更深入地了解该请求的响应。

响应 (The Response)

A Response is a powerful object for inspecting the results of the request. Let’s make that same request again, but this time store the return value in a variable so that you can get a closer look at its attributes and behaviors:

Response是检查请求结果的强大对象。 让我们再次发出相同的请求,但是这次将返回值存储在变量中,以便您可以更仔细地了解其属性和行为:

>>>
>>>
 >>>  response = requests . get ( 'https://api.github.com' )

In this example, you’ve captured the return value of get(), which is an instance of Response, and stored it in a variable called response. You can now use response to see a lot of information about the results of your GET request.

在此示例中,您捕获了get()的返回值get()它是Response的实例),并将其存储在名为response的变量中。 现在,您可以使用response来查看有关GET请求结果的大量信息。

状态码 (Status Codes)

The first bit of information that you can gather from Response is the status code. A status code informs you of the status of the request.

您可以从Response收集的第一部分信息是状态码。 状态代码会通知您请求的状态。

For example, a 200 OK status means that your request was successful, whereas a 404 NOT FOUND status means that the resource you were looking for was not found. There are many other possible status codes as well to give you specific insights into what happened with your request.

例如, 200 OK状态表示您的请求成功,而404 NOT FOUND状态表示未找到您要查找的资源。 还有许多其他可能的状态代码 ,可让您对请求发生的情况有具体的了解。

By accessing .status_code, you can see the status code that the server returned:

通过访问.status_code ,您可以看到服务器返回的状态代码:

>>>
>>>
 >>>  response . status_code
200

.status_code returned a 200, which means your request was successful and the server responded with the data you were requesting.

.status_code返回200 ,这意味着您的请求成功,并且服务器以您所请求的数据作为响应。

Sometimes, you might want to use this information to make decisions in your code:

有时,您可能希望使用此信息在代码中做出决定:

With this logic, if the server returns a 200 status code, your program will print Success!. If the result is a 404, your program will print Not Found.

按照这种逻辑,如果服务器返回200状态代码,则您的程序将打印Success! 。 如果结果是404 ,您的程序将打印Not Found

requests goes one step further in simplifying this process for you. If you use a Response instance in a conditional expression, it will evaluate to True if the status code was between 200 and 400, and False otherwise.

requests为您简化了这一过程又迈了一步。 如果在条件表达式中使用Response实例,则如果状态代码在200400之间,则它将评估为True ,否则为False

Therefore, you can simplify the last example by rewriting the if statement:

因此,您可以通过重写if语句来简化最后一个示例:

 if if responseresponse :
    :
    printprint (( 'Success!''Success!' )
)
elseelse :
    :
    printprint (( 'An error has occurred.''An error has occurred.' )
)

Technical Detail: This Truth Value Test is made possible because __bool__() is an overloaded method on Response.

技术细节:因为__bool__() Response 的重载方法 ,所以可以进行真值测试

This means that the default behavior of Response has been redefined to take the status code into account when determining the truth value of the object.

这意味着已重新定义Response的默认行为,以在确定对象的真值时考虑到状态码。

Keep in mind that this method is not verifying that the status code is equal to 200. The reason for this is that other status codes within the 200 to 400 range, such as 204 NO CONTENT and 304 NOT MODIFIED, are also considered successful in the sense that they provide some workable response.

请记住,此方法未验证状态码等于200 。 原因是200400范围内的其他状态代码(例如204 NO CONTENT304 NOT MODIFIED )也被认为是成功的,因为它们提供了一些可行的响应。

For example, the 204 tells you that the response was successful, but there’s no content to return in the message body.

例如, 204告诉您响应已成功,但是消息正文中没有返回的内容。

So, make sure you use this convenient shorthand only if you want to know if the request was generally successful and then, if necessary, handle the response appropriately based on the status code.

因此,请确保仅在想知道请求总体上是否成功后才使用此便捷的速记,然后在必要时根据状态代码适当地处理响应。

Let’s say you don’t want to check the response’s status code in an if statement. Instead, you want to raise an exception if the request was unsuccessful. You can do this using .raise_for_status():

假设您不想在if语句中检查响应的状态代码。 相反,如果请求失败,您想引发异常。 您可以使用.raise_for_status()进行此操作:

If you invoke .raise_for_status(), an HTTPError will be raised for certain status codes. If the status code indicates a successful request, the program will proceed without that exception being raised.

如果调用.raise_for_status() ,则将针对某些状态代码引发HTTPError 。 如果状态代码指示请求成功,则程序将继续运行而不会引发该异常。

Further Reading: If you’re not familiar with Python 3.6’s f-strings, I encourage you to take advantage of them as they are a great way to simplify your formatted strings.

进一步阅读:如果您不熟悉Python 3.6的f字符串 ,我建议您利用它们,因为它们是简化格式化字符串的好方法。

Now, you know a lot about how to deal with the status code of the response you got back from the server. However, when you make a GET request, you rarely only care about the status code of the response. Usually, you want to see more. Next, you’ll see how to view the actual data that the server sent back in the body of the response.

现在,您对如何处理从服务器返回的响应的状态代码非常了解。 但是,在发出GET请求时,您很少只关心响应的状态码。 通常,您想了解更多。 接下来,您将看到如何在响应的正文中查看服务器发送回的实际数据。

内容 (Content)

The response of a GET request often has some valuable information, known as a payload, in the message body. Using the attributes and methods of Response, you can view the payload in a variety of different formats.

GET请求的响应通常在消息正文中包含一些有价值的信息,称为有效负载。 使用Response的属性和方法,可以查看各种不同格式的有效负载。

To see the response’s content in bytes, you use .content:

要查看响应的内容(以bytes ,请使用.content

>>>
>>> response = requests.get('https://api.github.com')
>>> response.content
b'{"current_user_url":"https://api.github.com/user","current_user_authorizations_html_url":"https://github.com/settings/connections/applications{/client_id}","authorizations_url":"https://api.github.com/authorizations","code_search_url":"https://api.github.com/search/code?q={query}{&page,per_page,sort,order}","commit_search_url":"https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}","emails_url":"https://api.github.com/user/emails","emojis_url":"https://api.github.com/emojis","events_url":"https://api.github.com/events","feeds_url":"https://api.github.com/feeds","followers_url":"https://api.github.com/user/followers","following_url":"https://api.github.com/user/following{/target}","gists_url":"https://api.github.com/gists{/gist_id}","hub_url":"https://api.github.com/hub","issue_search_url":"https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}","issues_url":"https://api.github.com/issues","keys_url":"https://api.github.com/user/keys","notifications_url":"https://api.github.com/notifications","organization_repositories_url":"https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}","organization_url":"https://api.github.com/orgs/{org}","public_gists_url":"https://api.github.com/gists/public","rate_limit_url":"https://api.github.com/rate_limit","repository_url":"https://api.github.com/repos/{owner}/{repo}","repository_search_url":"https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}","current_user_repositories_url":"https://api.github.com/user/repos{?type,page,per_page,sort}","starred_url":"https://api.github.com/user/starred{/owner}{/repo}","starred_gists_url":"https://api.github.com/gists/starred","team_url":"https://api.github.com/teams","user_url":"https://api.github.com/users/{user}","user_organizations_url":"https://api.github.com/user/orgs","user_repositories_url":"https://api.github.com/users/{user}/repos{?type,page,per_page,sort}","user_search_url":"https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"}'

>>>

While .content gives you access to the raw bytes of the response payload, you will often want to convert them into a string using a character encoding such as UTF-8. response will do that for you when you access .text:

尽管.content使您可以访问响应有效负载的原始字节,但您通常会希望使用字符编码(例如UTF-8)将它们转换为字符串 。 访问.text时, response将为您做到这一点:

>>>
>>> response.text
'{"current_user_url":"https://api.github.com/user","current_user_authorizations_html_url":"https://github.com/settings/connections/applications{/client_id}","authorizations_url":"https://api.github.com/authorizations","code_search_url":"https://api.github.com/search/code?q={query}{&page,per_page,sort,order}","commit_search_url":"https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}","emails_url":"https://api.github.com/user/emails","emojis_url":"https://api.github.com/emojis","events_url":"https://api.github.com/events","feeds_url":"https://api.github.com/feeds","followers_url":"https://api.github.com/user/followers","following_url":"https://api.github.com/user/following{/target}","gists_url":"https://api.github.com/gists{/gist_id}","hub_url":"https://api.github.com/hub","issue_search_url":"https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}","issues_url":"https://api.github.com/issues","keys_url":"https://api.github.com/user/keys","notifications_url":"https://api.github.com/notifications","organization_repositories_url":"https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}","organization_url":"https://api.github.com/orgs/{org}","public_gists_url":"https://api.github.com/gists/public","rate_limit_url":"https://api.github.com/rate_limit","repository_url":"https://api.github.com/repos/{owner}/{repo}","repository_search_url":"https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}","current_user_repositories_url":"https://api.github.com/user/repos{?type,page,per_page,sort}","starred_url":"https://api.github.com/user/starred{/owner}{/repo}","starred_gists_url":"https://api.github.com/gists/starred","team_url":"https://api.github.com/teams","user_url":"https://api.github.com/users/{user}","user_organizations_url":"https://api.github.com/user/orgs","user_repositories_url":"https://api.github.com/users/{user}/repos{?type,page,per_page,sort}","user_search_url":"https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"}'

>>>

Because the decoding of bytes to a str requires an encoding scheme, requests will try to guess the encoding based on the response’s headers if you do not specify one. You can provide an explicit encoding by setting .encoding before accessing .text:

由于将bytes解码为str需要一种编码方案,因此,如果未指定,则requests将尝试根据响应的标头猜测编码 。 您可以通过在访问.text之前设置.encoding来提供显式编码:

>>>
>>> response.encoding = 'utf-8' # Optional: requests infers this internally
>>> response.text
'{"current_user_url":"https://api.github.com/user","current_user_authorizations_html_url":"https://github.com/settings/connections/applications{/client_id}","authorizations_url":"https://api.github.com/authorizations","code_search_url":"https://api.github.com/search/code?q={query}{&page,per_page,sort,order}","commit_search_url":"https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}","emails_url":"https://api.github.com/user/emails","emojis_url":"https://api.github.com/emojis","events_url":"https://api.github.com/events","feeds_url":"https://api.github.com/feeds","followers_url":"https://api.github.com/user/followers","following_url":"https://api.github.com/user/following{/target}","gists_url":"https://api.github.com/gists{/gist_id}","hub_url":"https://api.github.com/hub","issue_search_url":"https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}","issues_url":"https://api.github.com/issues","keys_url":"https://api.github.com/user/keys","notifications_url":"https://api.github.com/notifications","organization_repositories_url":"https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}","organization_url":"https://api.github.com/orgs/{org}","public_gists_url":"https://api.github.com/gists/public","rate_limit_url":"https://api.github.com/rate_limit","repository_url":"https://api.github.com/repos/{owner}/{repo}","repository_search_url":"https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}","current_user_repositories_url":"https://api.github.com/user/repos{?type,page,per_page,sort}","starred_url":"https://api.github.com/user/starred{/owner}{/repo}","starred_gists_url":"https://api.github.com/gists/starred","team_url":"https://api.github.com/teams","user_url":"https://api.github.com/users/{user}","user_organizations_url":"https://api.github.com/user/orgs","user_repositories_url":"https://api.github.com/users/{user}/repos{?type,page,per_page,sort}","user_search_url":"https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"}'

>>>

If you take a look at the response, you’ll see that it is actually serialized JSON content. To get a dictionary, you could take the str you retrieved from .text and deserialize it using json.loads(). However, a simpler way to accomplish this task is to use .json():

如果看一下响应,您将看到它实际上是序列化的JSON内容。 要获得字典,可以使用从.text检索的str并使用json.loads()将其反序列化。 但是,完成此任务的更简单方法是使用.json()

>>>
>>> response.json()
{'current_user_url': 'https://api.github.com/user', 'current_user_authorizations_html_url': 'https://github.com/settings/connections/applications{/client_id}', 'authorizations_url': 'https://api.github.com/authorizations', 'code_search_url': 'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}', 'commit_search_url': 'https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}', 'emails_url': 'https://api.github.com/user/emails', 'emojis_url': 'https://api.github.com/emojis', 'events_url': 'https://api.github.com/events', 'feeds_url': 'https://api.github.com/feeds', 'followers_url': 'https://api.github.com/user/followers', 'following_url': 'https://api.github.com/user/following{/target}', 'gists_url': 'https://api.github.com/gists{/gist_id}', 'hub_url': 'https://api.github.com/hub', 'issue_search_url': 'https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}', 'issues_url': 'https://api.github.com/issues', 'keys_url': 'https://api.github.com/user/keys', 'notifications_url': 'https://api.github.com/notifications', 'organization_repositories_url': 'https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}', 'organization_url': 'https://api.github.com/orgs/{org}', 'public_gists_url': 'https://api.github.com/gists/public', 'rate_limit_url': 'https://api.github.com/rate_limit', 'repository_url': 'https://api.github.com/repos/{owner}/{repo}', 'repository_search_url': 'https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}', 'current_user_repositories_url': 'https://api.github.com/user/repos{?type,page,per_page,sort}', 'starred_url': 'https://api.github.com/user/starred{/owner}{/repo}', 'starred_gists_url': 'https://api.github.com/gists/starred', 'team_url': 'https://api.github.com/teams', 'user_url': 'https://api.github.com/users/{user}', 'user_organizations_url': 'https://api.github.com/user/orgs', 'user_repositories_url': 'https://api.github.com/users/{user}/repos{?type,page,per_page,sort}', 'user_search_url': 'https://api.github.com/search/users?q={query}{&page,per_page,sort,order}'}

>>>

The type of the return value of .json() is a dictionary, so you can access values in the object by key.

.json()的返回值的type是字典,因此您可以通过键访问对象中的值。

You can do a lot with status codes and message bodies. But, if you need more information, like metadata about the response itself, you’ll need to look at the response’s headers.

您可以使用状态代码和消息正文来做很多事情。 但是,如果您需要更多信息,例如有关响应本身的元数据,则需要查看响应的标头。

标头 (Headers)

The response headers can give you useful information, such as the content type of the response payload and a time limit on how long to cache the response. To view these headers, access .headers:

响应标头可以为您提供有用的信息,例如响应有效负载的内容类型以及对响应进行缓存的时间限制。 要查看这些标题,请访问.headers

>>>
>>> response.headers
{'Server': 'GitHub.com', 'Date': 'Mon, 10 Dec 2018 17:49:54 GMT', 'Content-Type': 'application/json; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Status': '200 OK', 'X-RateLimit-Limit': '60', 'X-RateLimit-Remaining': '59', 'X-RateLimit-Reset': '1544467794', 'Cache-Control': 'public, max-age=60, s-maxage=60', 'Vary': 'Accept', 'ETag': 'W/"7dc470913f1fe9bb6c7355b50a0737bc"', 'X-GitHub-Media-Type': 'github.v3; format=json', 'Access-Control-Expose-Headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type', 'Access-Control-Allow-Origin': '*', 'Strict-Transport-Security': 'max-age=31536000; includeSubdomains; preload', 'X-Frame-Options': 'deny', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Referrer-Policy': 'origin-when-cross-origin, strict-origin-when-cross-origin', 'Content-Security-Policy': "default-src 'none'", 'Content-Encoding': 'gzip', 'X-GitHub-Request-Id': 'E439:4581:CF2351:1CA3E06:5C0EA741'}

>>>

.headers returns a dictionary-like object, allowing you to access header values by key. For example, to see the content type of the response payload, you can access Content-Type:

.headers返回类似于字典的对象,使您可以通过键访问标头值。 例如,要查看响应有效负载的内容类型,可以访问Content-Type

>>>
>>> response.headers['Content-Type']
'application/json; charset=utf-8'

>>>

There is something special about this dictionary-like headers object, though. The HTTP spec defines headers to be case-insensitive, which means we are able to access these headers without worrying about their capitalization:

但是,这种类似于字典的标头对象有一些特殊之处。 HTTP规范将标头定义为不区分大小写,这意味着我们能够访问这些标头而不必担心它们的大小写:

>>>
>>> response.headers['content-type']
'application/json; charset=utf-8'

>>>

Whether you use the key 'content-type' or 'Content-Type', you’ll get the same value.

无论您使用键'content-type'还是'Content-Type' ,您都将获得相同的值。

Now, you’ve learned the basics about Response. You’ve seen its most useful attributes and methods in action. Let’s take a step back and see how your responses change when you customize your GET requests.

现在,您已经了解了Response的基础知识。 您已经看到了其最有用的属性和方法。 让我们退后一步,看看自定义GET请求时响应如何变化。

查询字符串参数 (Query String Parameters)

One common way to customize a GET request is to pass values through query string parameters in the URL. To do this using get(), you pass data to params. For example, you can use GitHub’s Search API to look for the requests library:

定制GET请求的一种常用方法是通过URL中的查询字符串参数传递值。 要使用get()进行此操作,需要将数据传递给params 。 例如,您可以使用GitHub的Search API查找requests库:

 import import requests

requests

# Search GitHub's repositories for requests
# Search GitHub's repositories for requests
response response = = requestsrequests .. getget (
    (
    'https://api.github.com/search/repositories''https://api.github.com/search/repositories' ,
,
paramsparams == {{ 'q''q' : : 'requests+language:python''requests+language:python' },
},
)

)

# Inspect some attributes of the `requests` repository
# Inspect some attributes of the `requests` repository
json_response json_response = = responseresponse .. jsonjson ()
()
repository repository = = json_responsejson_response [[ 'items''items' ][][ 00 ]
]
printprint (( ff 'Repository name: 'Repository name:  {repository["name"]}{repository["name"]} '' )  )  # Python 3.6+
# Python 3.6+
printprint (( ff 'Repository description: 'Repository description:  {repository["description"]}{repository["description"]} '' )  )  # Python 3.6+
# Python 3.6+

By passing the dictionary {'q': 'requests+language:python'} to the params parameter of .get(), you are able to modify the results that come back from the Search API.

通过将字典{'q': 'requests+language:python'}传递给.get()params参数,您可以修改从Search API返回的结果。

You can pass params to get() in the form of a dictionary, as you have just done, or as a list of tuples:

您可以params做过的那样,以字典的形式或以元组列表的形式将params传递给get()

>>>
>>>
 >>>  requests . get (
...     'https://api.github.com/search/repositories' ,
...     params = [( 'q' , 'requests+language:python' )],
...  )
<Response [200]>

You can even pass the values as bytes:

您甚至可以将值作为bytes传递:

>>>
>>>
 >>>  requests . get (
...     'https://api.github.com/search/repositories' ,
...     params = b 'q=requests+language:python' ,
...  )
<Response [200]>

Query strings are useful for parameterizing GET requests. You can also customize your requests by adding or modifying the headers you send.

查询字符串对于参数化GET请求很有用。 您还可以通过添加或修改发送的标头来自定义请求。

请求标题 (Request Headers)

To customize headers, you pass a dictionary of HTTP headers to get() using the headers parameter. For example, you can change your previous search request to highlight matching search terms in the results by specifying the text-match media type in the Accept header:

要自定义标头,您get()使用headers参数将HTTP标头字典传递给get() 。 例如,您可以通过在Accept标头中指定text-match媒体类型,来更改先前的搜索请求,以在结果中突出显示匹配的搜索词:

The Accept header tells the server what content types your application can handle. In this case, since you’re expecting the matching search terms to be highlighted, you’re using the header value application/vnd.github.v3.text-match+json, which is a proprietary GitHub Accept header where the content is a special JSON format.

Accept标头告诉服务器您的应用程序可以处理哪些内容类型。 在这种情况下,由于您希望突出显示匹配的搜索词,因此您将使用标头值application/vnd.github.v3.text-match+json ,这是专有的GitHub Accept标头,其中内容为特殊的JSON格式。

Before you learn more ways to customize requests, let’s broaden the horizon by exploring other HTTP methods.

在学习更多定制请求的方法之前,让我们通过探索其他HTTP方法来拓宽视野。

其他HTTP方法 (Other HTTP Methods)

Aside from GET, other popular HTTP methods include POST, PUT, DELETE, HEAD, PATCH, and OPTIONS. requests provides a method, with a similar signature to get(), for each of these HTTP methods:

除了GET ,其他流行的HTTP方法还包括POSTPUTDELETEHEADPATCHOPTIONSrequests为每个以下HTTP方法提供了一种方法,该方法的签名与get()相似:

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

>>>

Each function call makes a request to the httpbin service using the corresponding HTTP method. For each method, you can inspect their responses in the same way you did before:

每个函数调用都使用相应的HTTP方法向httpbin服务发出请求。 对于每种方法,您都可以像以前一样检查它们的响应:

>>>
>>> response = requests.head('https://httpbin.org/get')
>>> response.headers['Content-Type']
'application/json'

>>> response = requests.delete('https://httpbin.org/delete')
>>> json_response = response.json()
>>> json_response['args']
{}

>>>

Headers, response bodies, status codes, and more are returned in the Response for each method. Next you’ll take a closer look at the POST, PUT, and PATCH methods and learn how they differ from the other request types.

每种方法的Response都返回标头,响应主体,状态码等。 接下来,您将仔细研究POSTPUTPATCH方法,并了解它们与其他请求类型的区别。

消息正文 (The Message Body)

According to the HTTP specification, POST, PUT, and the less common PATCH requests pass their data through the message body rather than through parameters in the query string. Using requests, you’ll pass the payload to the corresponding function’s data parameter.

根据HTTP规范, POSTPUT和不太常见的PATCH请求通过消息正文而不是通过查询字符串中的参数传递其数据。 使用requests ,您可以将有效负载传递给相应函数的data参数。

data takes a dictionary, a list of tuples, bytes, or a file-like object. You’ll want to adapt the data you send in the body of your request to the specific needs of the service you’re interacting with.

data使用字典,元组列表,字节或类似文件的对象。 您需要使在请求正文中发送的数据适应与之交互的服务的特定需求。

For example, if your request’s content type is application/x-www-form-urlencoded, you can send the form data as a dictionary:

例如,如果您请求的内容类型为application/x-www-form-urlencoded ,则可以将表单数据作为字典发送:

>>>
>>> requests.post('https://httpbin.org/post', data={'key':'value'})
<Response [200]>

>>>

You can also send that same data as a list of tuples:

您还可以将相同的数据作为元组列表发送:

>>>
>>> requests.post('https://httpbin.org/post', data=[('key', 'value')])
<Response [200]>

>>>

If, however, you need to send JSON data, you can use the json parameter. When you pass JSON data via json, requests will serialize your data and add the correct Content-Type header for you.

但是,如果需要发送JSON数据,则可以使用json参数。 当您通过json传递JSON数据时, requests将序列化您的数据并为您添加正确的Content-Type标头。

httpbin.org is a great resource created by the author of requests, Kenneth Reitz. It’s a service that accepts test requests and responds with data about the requests. For instance, you can use it to inspect a basic POST request:

httpbin.org是由requests的作者Kenneth Reitz创建的强大资源。 它是一项服务,接受测试请求并以有关请求的数据进行响应。 例如,您可以使用它来检查基本的POST请求:

>>>
>>> response = requests.post('https://httpbin.org/post', json={'key':'value'})
>>> json_response = response.json()
>>> json_response['data']
'{"key": "value"}'
>>> json_response['headers']['Content-Type']
'application/json'

>>>

You can see from the response that the server received your request data and headers as you sent them. requests also provides this information to you in the form of a PreparedRequest.

从响应中可以看到,服务器在发送请求数据和标头时已收到它们。 requests还以PreparedRequest的形式向您提供此信息。

检查您的请求 (Inspecting Your Request)

When you make a request, the requests library prepares the request before actually sending it to the destination server. Request preparation includes things like validating headers and serializing JSON content.

发出请求时, requests库在实际将请求发送到目标服务器之前会先准备好该请求。 请求准备包括验证标头和序列化JSON内容。

You can view the PreparedRequest by accessing .request:

您可以通过访问.request查看PreparedRequest

>>>
>>> response = requests.post('https://httpbin.org/post', json={'key':'value'})
>>> response.request.headers['Content-Type']
'application/json'
>>> response.request.url
'https://httpbin.org/post'
>>> response.request.body
b'{"key": "value"}'

>>>

Inspecting the PreparedRequest gives you access to all kinds of information about the request being made such as payload, URL, headers, authentication, and more.

通过检查PreparedRequest ,您可以访问有关所发出请求的各种信息,例如有效负载,URL,标头,身份验证等。

So far, you’ve made a lot of different kinds of requests, but they’ve all had one thing in common: they’re unauthenticated requests to public APIs. Many services you may come across will want you to authenticate in some way.

到目前为止,您已经提出了许多不同种类的请求,但是它们都有一个共同点:它们是对公共API的未经身份验证的请求。 您可能遇到的许多服务都希望您以某种方式进行身份验证。

认证方式 (Authentication)

Authentication helps a service understand who you are. Typically, you provide your credentials to a server by passing data through the Authorization header or a custom header defined by the service. All the request functions you’ve seen to this point provide a parameter called auth, which allows you to pass your credentials.

身份验证可帮助服务了解您的身份。 通常,您通过通过Authorization标头或服务定义的自定义标头传递数据来向服务器提供凭据。 到目前为止,您所看到的所有请求功能都提供了一个名为auth的参数,该参数使您可以传递凭据。

One example of an API that requires authentication is GitHub’s Authenticated User API. This endpoint provides information about the authenticated user’s profile. To make a request to the Authenticated User API, you can pass your GitHub username and password in a tuple to get():

需要身份验证的API的一个示例是GitHub的Authenticated User API。 该端点提供有关已认证用户的配置文件的信息。 要向Authenticated User API发出请求,您可以在元组中将GitHub用户名和密码传递给get()

>>>
>>> from getpass import getpass
>>> requests.get('https://api.github.com/user', auth=('username', getpass()))
<Response [200]>

>>>

The request succeeded if the credentials you passed in the tuple to auth are valid. If you try to make this request with no credentials, you’ll see that the status code is 401 Unauthorized:

如果您在元组中传递给auth的凭据有效,则请求成功。 如果您尝试不使用凭据发出此请求,则会看到状态码为401 Unauthorized

>>>
>>> requests.get('https://api.github.com/user')
<Response [401]>

>>>

When you pass your username and password in a tuple to the auth parameter, requests is applying the credentials using HTTP’s Basic access authentication scheme under the hood.

当您在元组中将用户名和密码传递给auth参数时, requests将在后台使用HTTP的基本访问身份验证方案来应用凭据。

Therefore, you could make the same request by passing explicit Basic authentication credentials using HTTPBasicAuth:

因此,您可以通过使用HTTPBasicAuth传递显式的基本身份验证凭据来HTTPBasicAuth相同的请求:

>>>
>>> from requests.auth import HTTPBasicAuth
>>> from getpass import getpass
>>> requests.get(
...     'https://api.github.com/user',
...     auth=HTTPBasicAuth('username', getpass())
... )
<Response [200]>

>>>

Though you don’t need to be explicit for Basic authentication, you may want to authenticate using another method. requests provides other methods of authentication out of the box such as HTTPDigestAuth and HTTPProxyAuth.

尽管您不需要显式进行基本身份验证,但是您可能希望使用其他方法进行身份验证。 requests提供了其他开箱即用的身份验证方法,例如HTTPDigestAuthHTTPProxyAuth

You can even supply your own authentication mechanism. To do so, you must first create a subclass of AuthBase. Then, you implement __call__():

您甚至可以提供自己的身份验证机制。 为此,您必须首先创建AuthBase的子类。 然后,您实现__call__()

 import import requests
requests
from from requests.auth requests.auth import import AuthBase

AuthBase

class class TokenAuthTokenAuth (( AuthBaseAuthBase ):
    ):
    """Implements a custom authentication scheme."""

    """Implements a custom authentication scheme."""

    def def __init____init__ (( selfself , , tokentoken ):
        ):
        selfself .. token token = = token

    token

    def def __call____call__ (( selfself , , rr ):
        ):
        """Attach an API token to a custom auth header."""
        """Attach an API token to a custom auth header."""
        rr .. headersheaders [[ 'X-TokenAuth''X-TokenAuth' ] ] = = ff '' {self.token}{self.token} '  '  # Python 3.6+
        # Python 3.6+
        return return r


r


requestsrequests .. getget (( 'https://httpbin.org/get''https://httpbin.org/get' , , authauth == TokenAuthTokenAuth (( '12345abcde-token''12345abcde-token' ))
))

Here, your custom TokenAuth mechanism receives a token, then includes that token in the X-TokenAuth header of your request.

在这里,您的自定义TokenAuth机制将收到一个令牌,然后将该令牌包含在您请求的X-TokenAuth标头中。

Bad authentication mechanisms can lead to security vulnerabilities, so unless a service requires a custom authentication mechanism for some reason, you’ll always want to use a tried-and-true auth scheme like Basic or OAuth.

错误的身份验证机制可能会导致安全漏洞,因此,除非服务出于某种原因需要自定义身份验证机制,否则您将始终希望使用经过验证的身份验证方案,例如Basic或OAuth。

While you’re thinking about security, let’s consider dealing with SSL Certificates using requests.

在考虑安全性时,让我们考虑使用requests处理SSL证书。

SSL证书验证 (SSL Certificate Verification)

Any time the data you are trying to send or receive is sensitive, security is important. The way that you communicate with secure sites over HTTP is by establishing an encrypted connection using SSL, which means that verifying the target server’s SSL Certificate is critical.

每当您尝试发送或接收的数据敏感时,安全性就很重要。 通过HTTP与安全站点进行通信的方式是通过使用SSL建立加密连接,这意味着验证目标服务器的SSL证书至关重要。

The good news is that requests does this for you by default. However, there are some cases where you might want to change this behavior.

好消息是,默认情况下, requests会为您执行此操作。 但是,在某些情况下,您可能需要更改此行为。

If you want to disable SSL Certificate verification, you pass False to the verify parameter of the request function:

如果要禁用SSL证书验证,请将False传递给请求函数的verify参数:

>>>
>>>
 >>>  requests . get ( 'https://api.github.com' , verify = False )
InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
<Response [200]>

requests even warns you when you’re making an insecure request to help you keep your data safe!

当您提出不安全的请求以保护您的数据安全时, requests甚至会警告您!

Note: requests uses a package called certifi to provide Certificate Authorities. This lets requests know which authorities it can trust. Therefore, you should update certifi frequently to keep your connections as secure as possible.

注意: requests使用称为certifi的包来提供证书颁发机构。 这样可以使requests知道它可以信任的权限。 因此,您应该经常更新certifi以确保连接尽可能安全。

性能 (Performance)

When using requests, especially in a production application environment, it’s important to consider performance implications. Features like timeout control, sessions, and retry limits can help you keep your application running smoothly.

在使用requests ,尤其是在生产应用程序环境中,考虑性能影响很重要。 超时控制,会话和重试限制等功能可以帮助您使应用程序平稳运行。

超时时间 (Timeouts)

When you make an inline request to an external service, your system will need to wait upon the response before moving on. If your application waits too long for that response, requests to your service could back up, your user experience could suffer, or your background jobs could hang.

当您向外部服务发出内联请求时,系统将需要等待响应才能继续。 如果您的应用程序等待该响应的时间太长,则可能会备份对服务的请求,可能会损害用户体验,或者可能会使后台作业挂起。

By default, requests will wait indefinitely on the response, so you should almost always specify a timeout duration to prevent these things from happening. To set the request’s timeout, use the timeout parameter. timeout can be an integer or float representing the number of seconds to wait on a response before timing out:

默认情况下, requests将无限期地等待响应,因此您几乎应始终指定超时时间以防止这些情况发生。 要设置请求的超时,请使用timeout参数。 timeout可以是整数或浮点数,表示timeout前等待响应的秒数:

>>>
>>>
 >>>  requests . get ( 'https://api.github.com' , timeout = 1 )
<Response [200]>
>>>  requests . get ( 'https://api.github.com' , timeout = 3.05 )
<Response [200]>

In the first request, the request will timeout after 1 second. In the second request, the request will timeout after 3.05 seconds.

在第一个请求中,该请求将在1秒后超时。 在第二个请求中,该请求将在3.05秒后超时。

You can also pass a tuple to timeout with the first element being a connect timeout (the time it allows for the client to establish a connection to the server), and the second being a read timeout (the time it will wait on a response once your client has established a connection):

您还可以将元组传递timeout ,第一个元素是连接超时(客户端允许与服务器建立连接的时间),第二个元素是读取超时(等待响应一次的时间)您的客户已建立连接):

>>>
>>>
 >>>  requests . get ( 'https://api.github.com' , timeout = ( 2 , 5 ))
<Response [200]>

If the request establishes a connection within 2 seconds and receives data within 5 seconds of the connection being established, then the response will be returned as it was before. If the request times out, then the function will raise a Timeout exception:

如果请求在建立连接的2秒内建立了连接,并在建立连接的5秒内接收到数据,则将像以前一样返回响应。 如果请求超时,则该函数将引发Timeout异常:

Your program can catch the Timeout exception and respond accordingly.

您的程序可以捕获Timeout异常并做出相应的响应。

会话对象 (The Session Object)

Until now, you’ve been dealing with high level requests APIs such as get() and post(). These functions are abstractions of what’s going on when you make your requests. They hide implementation details such as how connections are managed so that you don’t have to worry about them.

到目前为止,您一直在处理高级requests API,例如get()post() 。 这些函数是您发出请求时所发生情况的抽象。 它们隐藏了实现细节,例如如何管理连接,因此您不必担心它们。

Underneath those abstractions is a class called Session. If you need to fine-tune your control over how requests are being made or improve the performance of your requests, you may need to use a Session instance directly.

这些抽象的下面是一个称为Session的类。 如果需要微调对发出请求的方式的控制或提高请求的性能,则可能需要直接使用Session实例。

Sessions are used to persist parameters across requests. For example, if you want to use the same authentication across multiple requests, you could use a session:

会话用于在请求之间保留参数。 例如,如果要在多个请求中使用相同的身份验证,则可以使用会话:

 import import requests
requests
from from getpass getpass import import getpass

getpass

# By using a context manager, you can ensure the resources used by
# By using a context manager, you can ensure the resources used by
# the session will be released after use
# the session will be released after use
with with requestsrequests .. SessionSession () () as as sessionsession :
    :
    sessionsession .. auth auth = = (( 'username''username' , , getpassgetpass ())

    ())

    # Instead of requests.get(), you'll use session.get()
    # Instead of requests.get(), you'll use session.get()
    response response = = sessionsession .. getget (( 'https://api.github.com/user''https://api.github.com/user' )

)

# You can inspect the response just like you did before
# You can inspect the response just like you did before
printprint (( responseresponse .. headersheaders )
)
printprint (( responseresponse .. jsonjson ())
())

Each time you make a request with session, once it has been initialized with authentication credentials, the credentials will be persisted.

每次使用session发出请求时,一旦使用身份验证凭据对其进行了初始化,则该凭据将被保留。

The primary performance optimization of sessions comes in the form of persistent connections. When your app makes a connection to a server using a Session, it keeps that connection around in a connection pool. When your app wants to connect to the same server again, it will reuse a connection from the pool rather than establishing a new one.

会话的主要性能优化以持久连接的形式出现。 当您的应用程序使用Session与服务器建立连接时,它将在连接池中保持该连接。 当您的应用程序想要再次连接到同一服务器时,它将重用来自池的连接,而不是建立新的连接。

最大重试次数 (Max Retries)

When a request fails, you may want your application to retry the same request. However, requests will not do this for you by default. To apply this functionality, you need to implement a custom Transport Adapter.

当请求失败时,您可能希望您的应用程序重试相同的请求。 但是,默认情况下, requests不会为您执行此操作。 要应用此功能,您需要实现一个自定义的传输适配器

Transport Adapters let you define a set of configurations per service you’re interacting with. For example, let’s say you want all requests to https://api.github.com to retry three times before finally raising a ConnectionError. You would build a Transport Adapter, set its max_retries parameter, and mount it to an existing Session:

传输适配器使您可以为与之交互的每个服务定义一组配置。 例如,假设您希望对https://api.github.com所有请求重试3次,最后才引发ConnectionError 。 您将构建一个传输适配器,设置其max_retries参数,并将其安装到现有的Session

When you mount the HTTPAdapter, github_adapter, to session, session will adhere to its configuration for each request to https://api.github.com.

当您将HTTPAdapter github_adapter挂载到sessionsession将遵循对https://api.github.com的每个请求的配置。

Timeouts, Transport Adapters, and sessions are for keeping your code efficient and your application resilient.

超时,传输适配器和会话用于保持代码高效和应用程序弹性。

结论 (Conclusion)

You’ve come a long way in learning about Python’s powerful requests library.

在学习Python强大的requests库方面,您已经走了很长一段路。

You’re now able to:

您现在可以:

  • Make requests using a variety of different HTTP methods such as GET, POST, and PUT
  • Customize your requests by modifying headers, authentication, query strings, and message bodies
  • Inspect the data you send to the server and the data the server sends back to you
  • Work with SSL Certificate verification
  • Use requests effectively using max_retries, timeout, Sessions, and Transport Adapters
  • 使用各种不同的HTTP方法(例如GETPOSTPUT发出请求
  • 通过修改标题,身份验证,查询字符串和消息正文来自定义您的请求
  • 检查您发送到服务器的数据以及服务器发送回给您的数据
  • 使用SSL证书验证
  • 通过使用max_retriestimeout ,Sessions和Transport Adapter有效地使用requests

Because you learned how to use requests, you’re equipped to explore the wide world of web services and build awesome applications using the fascinating data they provide.

由于您已经学会了如何使用requests ,因此您可以探索Web服务的广阔世界,并使用它们提供的引人入胜的数据来构建出色的应用程序。

翻译自: https://www.pybloggers.com/2019/01/pythons-requests-library-guide/

python 请求kv库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值