轻松搞定网络请求:玩转Python中requests模块

介绍

在Python中,requests库是用于发送HTTP请求的常用库。它提供了简洁易用的接口,使得发送HTTP请求变得非常简单。

requests库默认使用HTTP/1.1协议发送请求,这是因为HTTP/1.1是互联网上广泛采用的标准版本,它比早期的HTTP/1.0提供了更多的功能,如持久连接(keep-alive)、管道化请求(pipelining)以及更丰富的状态管理等。requests库本身并不直接控制HTTP协议的版本,而是通过底层的传输层如urllib3库来发送请求。urllib3通常会根据服务器的支持情况自动选择合适的HTTP版本,但在大多数情况下,这将是HTTP/1.1。随着HTTP/2的普及,requests库也支持了对HTTP/2的透明使用,但这通常需要底层的urllib3库以及Python环境中的其他依赖项(如pyOpenSSL, ndg-httpsclient, 和 pyasn1)的支持。如果这些依赖项存在并且服务器支持HTTP/2,那么requests库能够自动利用HTTP/2的特性,如多路复用和头部压缩,以提高性能。在使用requests时,如果你的环境中正确安装了上述依赖库,你不需要做任何特别的配置,requests会自动尝试使用HTTP/2,如果服务器支持HTTP/2的话。

1. 安装requests库

使用以下命令来安装requests库:

pip install requests

2. 发送没有参数的GET请求

requests库中的get()函数可以用于发送GET请求。

import requests

# 发送GET请求
response = requests.get('https://baidu.com')

# 输出响应内容
print(response.text)

这段Python代码使用requests库向百度的主页发送了一个GET请求,并打印出了服务器返回的HTML内容。

3. 发送带参数的GET请求

有时候我们需要发送带参数的GET请求。

为了演示如何使用requests库发送带参数的GET请求,我们可以使用一个公开的、无需认证的API,例如“httpbin.org”,它是一个用于测试HTTP请求的工具网站。

下面是一个使用requestshttpbin.org发送GET请求的例子,其中包含了查询参数:

import requests

# 发送带参数的GET请求
params = {'key': 'value'}
response = requests.get('https://httpbin.org/get', params=params)

# 输出响应内容
print(response.text)

在这个例子中,我们将https://httpbin.org/get作为目标URL。httpbin.org/get会返回一个JSON格式的响应,其中包括了发送请求的所有细节,如请求的URL、请求头、查询参数等。

运行上述代码,你会看到一个JSON响应,类似于下面的内容:

{
  "args": {
    "key": "value"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.x.y",
    ...
  },
  "origin": "your_ip_address",
  "url": "https://httpbin.org/get?key=value"
}

Origin请求头在HTTP请求中用于指示请求的来源,也就是你的ip地址

4. 发送POST请求

requests库中的post()函数可以用于发送POST请求。

import requests

# 要发送的数据
data = {'key1': 'value1', 'key2': 'value2'}

# 发送POST请求
response = requests.post('https://httpbin.org/post', data=data)


# 检查请求是否成功
if response.status_code == 200:
    # 打印响应的JSON内容
    print(response.text)
else:
    print(f"Request failed with status code: {response.status_code}")

返回值

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "23", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.32.3", 
    "X-Amzn-Trace-Id": "Root=1-669a0c22-08a19a51643620016a199398"
  }, 
  "json": null, 
  "origin": "your_id", 
  "url": "https://httpbin.org/post"
}

数据通过form字段发送,所以"data"字段为空。
"files": {} 这个字段用于显示是否有任何文件作为POST数据的一部分发送
在使用requests库发送POST请求时,默认情况下,如果你将数据作为一个字典传递给data参数,requests会自动将这些数据编码为application/x-www-form-urlencoded格式,这就是所谓的“表单编码”。这种编码方式是Web表单提交数据时最常用的一种格式,它将字典中的键值对转换为形如key1=value1&key2=value2的字符串,然后放在请求体中发送。"form"这个字段包含了通过application/x-www-form-urlencoded格式发送的表单数据。
"X-Amzn-Trace-Id": "Root=1-669a0753-735ffa9b5d6fad806a76331f" 可能是AWS X-Ray跟踪ID,用于分布式追踪。

5. 发送JSON数据

requests库中的post()函数也可以用于发送JSON数据。

import requests

# 要发送的数据
#data = {'key1': 'value1', 'key2': 'value2'}

# 发送POST请求
#response = requests.post('https://httpbin.org/post', data=data)

data = {'key1': 'value1', 'key2': 'value2'}

response = requests.post('https://httpbin.org/post', json=data)


# 检查请求是否成功
if response.status_code == 200:
    # 打印响应的JSON内容
    print(response.text)
else:
    print(f"Request failed with status code: {response.status_code}")

在httpbin.org/post的响应中,data字段显示的是请求体中原始JSON数据的字符串表示。data字段在使用json参数时包含的是原始的JSON字符串,而json字段则是解析后的数据。对于json数据,data字段并非仅限于未被解析的数据,而是包含了请求体中以字符串形式的全部数据。在使用json参数时,data字段反映了发送的实际JSON字符串内容

{
  "args": {}, 
  "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "36", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.32.3", 
    "X-Amzn-Trace-Id": "Root=1-669a1133-28a9105c7eddd4284a0b002f"
  }, 
  "json": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "origin": "39.109.69.59", 
  "url": "https://httpbin.org/post"
}

6. 发送文件

使用requests库向https://httpbin.org发送文件,你需要使用https://httpbin.org/post端点,因为httpbin.org使用/post来接收任意类型的POST数据,包括文件上传。

import requests

# 文件路径
file_path = 'data.txt' #内容是abcd1234

# 以二进制模式打开文件
with open(file_path, 'rb') as file:
    # 创建文件字典,其中'file'是服务器期望的参数名
    files = {'file': ('data.txt', file)}

    # 发送POST请求
    response = requests.post('https://httpbin.org/post', files=files)

# 输出响应内容
print(response.text)

响应
 

{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "abcd1234"
  }, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "152", 
    "Content-Type": "multipart/form-data; boundary=77f4b2e43597102f99fc392557813dd2", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.32.3", 
    "X-Amzn-Trace-Id": "Root=1-669a137f-12a750ad3ac828a80ae3959c"
  }, 
  "json": null, 
  "origin": "your_id", 
  "url": "https://httpbin.org/post"
}

7. 设置请求头

有时候我们需要设置请求头,以便向服务器传递更多信息, 使用headers参数设置请求头。

import requests

# 设置请求头
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get('https://httpbin.org/get', headers=headers)

# 输出响应内容
print(response.text)

可以看到返回的User-Agent和设置的一样

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0", 
    "X-Amzn-Trace-Id": "Root=1-669a15db-06e5d844239a1ad5698cb1a0"
  }, 
  "origin": "your_id", 
  "url": "https://httpbin.org/get"
}

8. 设置超时时间

在发送请求时,有时候我们需要设置超时时间,防止请求时间过长。

选择一个可能需要较长时间才能响应或根本不响应的URL,或者使用一个工具网站如httpbin.org/delay/{seconds},它会故意延迟响应,以便于测试超时设置。这里设置超时限制为5秒,但是我们让网站延迟10秒再响应

import requests
from requests.exceptions import Timeout

# 设置超时时间为5秒
timeout = 5

try:
    # 发送GET请求,使用httpbin.org/delay/10,它会延迟10秒才响应
    response = requests.get('https://httpbin.org/delay/10', timeout=timeout)
except Timeout:
    print("The request timed out")
else:
    # 输出响应内容
    print(response.text)

 运行如预期一样,报超时错误

The request timed out

9. 处理响应

requests库返回的响应是一个Response对象,我们可以通过该对象获取响应的各种信息。

使用response.status_code获取响应状态码,使用response.headers获取响应头,使用response.text获取响应内容,并将这些信息输出。

import requests

# 发送GET请求
response = requests.get('https://httpbin.org/get')

# 获取响应状态码
status_code = response.status_code

# 获取响应头
headers = response.headers

# 获取响应内容
content = response.text

# 输出响应状态码、响应头和响应内容
print("状态码:", status_code)
print("响应头:", headers)
print("响应内容:", content)
状态码: 200
响应头: {'Date': 'Fri, 19 Jul 2024 07:45:59 GMT', 'Content-Type': 'application/json', 'Content-Length': '306', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
响应内容: {
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.32.3", 
    "X-Amzn-Trace-Id": "Root=1-669a19b7-30a2b78b27bab21519607247"
  }, 
  "origin": "your_id", 
  "url": "https://httpbin.org/get"
}

请求行由(123)组成:1是请求方法;2是url地址,它和报文头的Host属性组成完整的请求URL;3是协议名称和版本号。

请求头(4):是HTTP的报文头,报文头包含若干个属性,格式均为"属性名:属性值",服务端由此获得客户端的信息。与缓存有关的信息都放在头部(header)。

请求体(5):它保存的就是前面post方法中说的将data字典转为的application/x-www-form-urlencoded格式

10. 异常处理

在发送请求时,可能会发生一些异常,我们需要进行适当的异常处理。

import requests

try:
    # 发送GET请求
    response = requests.get('https://httpbin.org/get')

    # 如果响应状态码不为200,抛出异常
    response.raise_for_status()

    # 输出响应内容
    print(response.text)
except requests.exceptions.HTTPError as http_error:
    print("HTTP错误:", http_error)
except requests.exceptions.ConnectionError as connection_error:
    print("连接错误:", connection_error)
except requests.exceptions.Timeout as timeout_error:
    print("超时错误:", timeout_error)
except requests.exceptions.RequestException as request_exception:
    print("其他错误:", request_exception)

如果响应状态码不为200,则使用response.raise_for_status()抛出异常。除了HTTPError异常,requests库还可能抛出ConnectionError、Timeout和RequestException等异常。

11.会话管理

有时候我们需要在多个请求之间保持一些状态信息,可以使用Session对象进行会话管理。

import requests

# 创建Session对象
s = requests.Session()

# 发送第一个请求,可能设置或更新cookies
r1 = s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
print(r1.text)

# 发送第二个请求,自动携带上次请求的cookies
r2 = s.get('https://httpbin.org/cookies')
print(r2.text)

cookies信息保留下来了

12.SSL证书验证

在发送HTTPS请求时,默认会验证服务器的SSL证书。如果不想验证,可以设置verify参数为False。

import requests

# 发送HTTPS请求,不验证SSL证书
response = requests.get('https://httpbin.org/get', verify=False)

# 输出响应内容
print(response.text)

13. 代理设置

有时候我们需要通过代理服务器发送请求,可以通过proxies参数进行设置。

import requests

# 设置代理
proxies = {'http': 'http://user:password@proxy.example.com',
           'https': 'https://user:password@proxy.example.com'}
response = requests.get('https://httpbin.org/get', proxies=proxies)

# 输出响应内容
print(response.text)

总结

requests库确实是Python开发者进行网络编程时不可或缺的工具,简化了许多网络请求的复杂性,使得HTTP请求变得简单而直观。从发送GET请求、发送带参数的GET请求,到发送POST请求、发送带参数的POST请求,再到发送JSON数据和文件,以及设置请求头、超时时间,处理响应和异常,会话管理,SSL证书验证和代理设置。熟练掌握requests库的使用,不仅可以提高开发效率,还能帮助开发者构建出更加可靠和高效的网络应用。无论是在数据抓取、API调用、自动化测试,还是在构建微服务架构中,requests都是一个强大而灵活的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值