目录
引言
HTTP协议是互联网上最常用的协议之一,掌握HTTP协议以及如何使用Python的requests模块来发送HTTP请求,对于数据抓取、API调用等任务至关重要。本文将从HTTP协议的基础知识出发,详细介绍如何使用requests模块发送GET和POST请求、处理响应数据、添加请求头、处理异常等,并通过多个实际案例帮助新手朋友快速上手。
一、HTTP协议基础
HTTP(HyperText Transfer Protocol)协议,即超文本传输协议,是一种请求-响应式协议。客户端(如浏览器)发起HTTP请求,服务器对请求作出响应。HTTP协议基于TCP协议进行数据的可靠传输,常用的端口号是80(HTTP)和443(HTTPS)。
1. URL解析
URL(Uniform Resource Locator)是统一资源定位符,用于定位互联网上的资源。HTTP URL的常用格式如下:
http://<host>:<port>/<path>?<query>
- host:表示主机的域名或IP地址。
- port:表示TCP连接的端口号,可以省略,此时将使用HTTP协议的默认端口号80。
- path:表示资源在服务器主机中的路径,以“/”符号进行路径的连接。
- query:表示查询字符串,格式为name1=value1&name2=value2,用于在请求中携带参数。
2. 请求方法
HTTP协议定义了多种请求方法,常用的包括GET和POST。
- GET:用于请求资源,是读操作,幂等请求(多次请求与一次请求的效果相同)。
- POST:用于提交数据,常用于创建新资源。
3. 请求与响应格式
HTTP请求格式分为请求行、请求头和请求体。
- 请求行:METHOD URL HTTP/VERSION CRLF
- METHOD:请求方法,如GET、POST。
- URL:请求资源的地址。
- HTTP/VERSION:HTTP版本信息,如HTTP/1.1、HTTP/2.0。
- CRLF:回车换行符。
- 请求头:包含字段名/字段值对,格式为字段名:字段值。
- 请求体:通常包含请求的参数信息,GET请求的请求体一般为空。
- HTTP响应格式分为状态行、响应头和响应体。
- 状态行:HTTP/VERSION STATUS REASON CRLF
- HTTP/VERSION:HTTP版本信息。
- STATUS:状态码,表示服务器的处理状态。
- REASON:状态码的描述信息。
- CRLF:回车换行符。
- 响应头:包含字段名/字段值对,格式为字段名:字段值。
- 响应体:表示响应的具体内容。
4. 常用状态码
HTTP状态码用于表示服务器的处理状态,常见的状态码包括:
- 200 OK:请求成功。
- 404 Not Found:请求的资源未找到。
- 500 Internal Server Error:服务器内部错误。
二、requests模块基础
requests模块是Python中一个简单易用的HTTP库,用于发送HTTP请求。requests模块默认使用HTTP/1.1协议,但在支持HTTP/2的环境中,也可以自动利用HTTP/2的特性。
1. 安装requests模块
使用pip命令安装requests模块:
pip install requests
2. 发送GET请求
使用requests模块中的get()函数可以发送GET请求。
import requests
# 发送GET请求
response = requests.get('https://baidu.com')
# 输出响应内容
print(response.text)
上述代码向百度的主页发送了一个GET请求,并打印出了服务器返回的HTML内容。
3. 发送带参数的GET请求
发送带参数的GET请求时,可以将参数以字典的形式传递给params参数。
import requests
# 发送带参数的GET请求
params = {'key': 'value'}
response = requests.get('https://httpbin.org/get', params=params)
# 输出响应内容
print(response.json())
上述代码向httpbin.org/get发送了一个带有查询参数的GET请求,并打印出了JSON格式的响应内容。
4. 发送POST请求
使用requests模块中的post()函数可以发送POST请求。
import requests
# 要发送的数据
data = {'key1': 'value1', 'key2': 'value2'}
# 发送POST请求
response = requests.post('https://httpbin.org/post', data=data)
# 输出响应内容
print(response.text)
上述代码向httpbin.org/post发送了一个POST请求,并打印出了响应内容。
requests模块会自动将data参数中的数据编码为application/x-www-form-urlencoded格式,即表单编码。
5. 发送JSON数据
发送JSON格式的POST请求时,可以将数据以字典的形式传递给json参数。
import requests
# 要发送的数据
data = {'key1': 'value1', 'key2': 'value2'}
# 发送JSON格式的POST请求
response = requests.post('https://httpbin.org/post', json=data)
# 输出响应内容
print(response.text)
上述代码向httpbin.org/post发送了一个包含JSON数据的POST请求,并打印出了响应内容。
6. 添加请求头
在发送HTTP请求时,可以通过headers参数添加请求头。
import requests
# 发送GET请求,添加请求头
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get('https://baidu.com', headers=headers)
# 输出响应内容
print(response.text)
上述代码向百度的主页发送了一个带有自定义User-Agent的GET请求。
7. 处理JSON响应
如果响应内容是JSON格式,可以使用response.json()方法解析JSON数据。
import requests
# 发送GET请求,处理JSON响应
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
data = response.json()
# 输出JSON数据
print(data)
上述代码向jsonplaceholder.typicode.com/posts/1发送了一个GET请求,并解析了JSON格式的响应内容。
8. 处理错误和异常
requests模块可能会抛出异常,例如网络连接问题或HTTP错误。可以使用try...except块来处理这些异常。
import requests
from requests.exceptions import RequestException, Timeout
try:
# 设置超时时间为5秒,发送GET请求,处理错误和异常
response = requests.get('https://baidu.com', timeout=5)
response.raise_for_status() # 如果响应状态码不是200,抛出异常
print(response.text)
except Timeout:
print("请求超时")
except RequestException as e:
print(f"请求失败: {e}")
上述代码在发送GET请求时设置了超时时间,并处理了可能抛出的超时异常和请求异常。
三、requests模块高级用法
1. 会话对象(Session)
使用会话对象可以跨请求保持某些参数,如cookies、请求头等。
import requests
# 创建会话对象
session = requests.Session()
# 设置请求头
session.headers.update({'User-Agent': 'Mozilla/5.0'})
# 发送GET请求
response = session.get('https://baidu.com')
# 输出响应内容
print(response.text)
上述代码创建了一个会话对象,并设置了自定义的User-Agent,然后发送了一个GET请求。
2. 文件上传
使用files参数可以发送带有文件上传的POST请求。
import requests
# 要上传的文件
files = {'file': open('example.txt', 'rb')}
# 发送文件上传的POST请求
response = requests.post('https://httpbin.org/post', files=files)
# 输出响应内容
print(response.text)
上述代码向httpbin.org/post发送了一个包含文件上传的POST请求。
3. 代理设置
可以通过proxies参数设置代理。
import requests
# 代理设置
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
# 发送GET请求,使用代理
response = requests.get('https://www.zdaye.com', proxies=proxies)
# 输出响应内容
print(response.text)
上述代码设置了HTTP和HTTPS的代理,并通过代理发送了一个GET请求到`example.com`。
4. Cookies处理
requests模块会自动处理cookies,如果需要手动添加或获取cookies,可以使用`requests.Session()`对象。
import requests
# 创建会话对象
session = requests.Session()
# 发送GET请求,获取cookies
response = session.get('https://example.com')
# 获取cookies
cookies = session.cookies.get_dict()
print(cookies)
# 设置cookies
session.cookies.set('example_cookie', 'example_value')
# 再次发送GET请求,携带cookies
response = session.get('https://example.com')
print(response.text)
上述代码创建了一个会话对象,通过GET请求获取了cookies,并手动设置了一个cookie,然后再次发送GET请求时携带了这个cookie。
5. 超时设置
在发送请求时,可以通过timeout参数设置超时时间。
import requests
try:
# 发送GET请求,设置超时时间为5秒
response = requests.get('https://example.com', timeout=5)
print(response.text)
except requests.exceptions.Timeout:
print("请求超时")
上述代码在发送GET请求时设置了超时时间为5秒,如果请求超过这个时间还没有响应,就会抛出requests.exceptions.Timeout异常。
6. 重定向与禁用重定向
requests模块默认会处理HTTP重定向。如果需要禁用重定向,可以将allow_redirects参数设置为False。
import requests
# 发送GET请求,禁用重定向
response = requests.get('https://example.com', allow_redirects=False)
print(response.status_code)
print(response.headers)
上述代码发送了一个GET请求到example.com,并禁用了重定向,打印出了响应的状态码和头部信息。
7. 验证SSL证书
在默认情况下,requests模块会验证SSL证书。如果服务器使用的是自签名证书,可以通过verify参数禁用SSL证书验证。
import requests
# 发送GET请求,禁用SSL证书验证
response = requests.get('https://self-signed.badssl.com/', verify=False)
print(response.text)
注意:禁用SSL证书验证会降低安全性,因此在实际应用中应尽量避免。
8. 自定义认证
如果需要发送带有HTTP认证的请求,可以使用auth参数。
import requests
from requests.auth import HTTPBasicAuth
# 发送GET请求,使用HTTP基本认证
response = requests.get('https://example.com/protected', auth=HTTPBasicAuth('username', 'password'))
print(response.text)
上述代码使用HTTP基本认证发送了一个GET请求到受保护的资源。
四、总结
requests模块是一个功能强大且易于使用的HTTP库,适用于各种HTTP请求场景。通过本文的介绍,你可以掌握requests模块的基本用法和高级特性,包括发送GET和POST请求、处理响应数据、添加请求头、处理异常、会话对象、文件上传、代理设置、Cookies处理、超时设置、重定向处理、SSL证书验证和自定义认证等。
希望本文能帮助你更好地理解和使用requests模块,成为HTTP请求的高手。如果你有任何问题或建议,请随时留言交流。