http.client 教程-如何使用 Python 标准库发送 HTTP 请求
http.client 教程-如何使用 Python 标准库发送 HTTP 请求
以下是 http.client 模块的详细使用教程,帮助你理解如何使用 Python 标准库发送 HTTP 请求:
1. http.client 概述
http.client 是 Python 内置的 HTTP 客户端库,提供了底层的 HTTP 协议实现,支持:
优点:无需额外安装依赖,适合轻量级 HTTP 交互。
缺点:API 较为底层,使用复杂度高于 requests 库。
2. 基本使用流程
步骤 1:导入模块并创建连接
import http.client
# HTTP 连接
conn = http.client.HTTPConnection(\"example.com\")
# HTTPS 连接(默认端口 443)
conn = http.client.HTTPSConnection(\"api.example.com\")
# 指定端口(如 8080)
conn = http.client.HTTPConnection(\"localhost\", 8080)
步骤 2:发送请求
# 发送 GET 请求
conn.request(\"GET\", \"/path/to/resource\")
# 发送带参数的 GET 请求
conn.request(\"GET\", \"/search?q=python&page=1\")
# 发送 POST 请求(带 JSON 数据)
headers = {\"Content-Type\": \"application/json\"}
body = \'{\"name\": \"test\", \"age\": 30}\'
conn.request(\"POST\", \"/users\", body, headers)
步骤 3:获取响应
response = conn.getresponse()
# 获取响应状态码
status_code = response.status # 如 200, 404, 500
# 获取响应头
headers = response.getheaders()
# 获取响应内容
data = response.read() # 返回 bytes 类型
text = data.decode(\"utf-8\") # 转为字符串
步骤 4:关闭连接
conn.close()
3. 处理不同类型的请求
GET 请求示例
import http.client
conn = http.client.HTTPSConnection(\"jsonplaceholder.typicode.com\")
conn.request(\"GET\", \"/posts/1\")
response = conn.getresponse()
print(f\"状态码: {response.status}\")
print(f\"响应头: {response.getheaders()}\")
print(f\"响应内容: {response.read().decode()}\")
conn.close()
POST 请求示例(JSON 数据)
import http.client
import json
conn = http.client.HTTPSConnection(\"jsonplaceholder.typicode.com\")
headers = {\"Content-Type\": \"application/json\"}
body = json.dumps({\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1})
conn.request(\"POST\", \"/posts\", body, headers)
response = conn.getresponse()
print(response.read().decode())
conn.close()
带参数的 POST 请求(表单数据)
import http.client
from urllib.parse import urlencode
conn = http.client.HTTPConnection(\"example.com\")
headers = {\"Content-Type\": \"application/x-www-form-urlencoded\"}
params = urlencode({\"username\": \"test\", \"password\": \"123456\"})
conn.request(\"POST\", \"/login\", params, headers)
response = conn.getresponse()
print(response.read().decode())
conn.close()
4. 处理响应
响应状态码
if response.status == 200:
print(\"请求成功\")
elif response.status == 404:
print(\"资源不存在\")
else:
print(f\"错误: {response.status}\")
响应头处理
# 获取特定头信息
content_type = response.getheader(\"Content-Type\")
print(f\"内容类型: {content_type}\")
# 获取所有头信息
headers = response.getheaders()
for header, value in headers:
print(f\"{header}: {value}\")
响应内容处理
# 读取二进制内容
data = response.read()
# 根据 Content-Type 解码
content_type = response.getheader(\"Content-Type\")
if \"json\" in content_type:
import json
json_data = json.loads(data)
elif \"text\" in content_type:
text = data.decode(\"utf-8\")
else:
# 二进制数据(如图像、文件)
with open(\"file.bin\", \"wb\") as f:
f.write(data)
5. 高级用法
设置超时时间
conn = http.client.HTTPSConnection(\"example.com\", timeout=5) # 5秒超时
处理重定向(301/302)
max_redirects = 3
current_url = \"/initial-path\"
redirect_count = 0
while redirect_count < max_redirects:
conn.request(\"GET\", current_url)
response = conn.getresponse()
if response.status in (301, 302):
location = response.getheader(\"Location\")
current_url = location
redirect_count += 1
else:
break # 非重定向状态码,退出循环
设置请求头(如 User-Agent)
headers = {
\"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\",
\"Accept\": \"application/json\"
}
conn.request(\"GET\", \"/api/data\", headers=headers)
基本认证
import base64
username = \"admin\"
password = \"secret\"
auth_string = f\"{username}:{password}\"
auth_bytes = base64.b64encode(auth_string.encode())
auth_header = f\"Basic {auth_bytes.decode()}\"
headers = {\"Authorization\": auth_header}
conn.request(\"GET\", \"/protected\", headers=headers)
6. 异常处理
import http.client
try:
conn = http.client.HTTPSConnection(\"nonexistent-domain.com\")
conn.request(\"GET\", \"/\")
response = conn.getresponse()
except ConnectionRefusedError:
print(\"连接被拒绝\")
except TimeoutError:
print(\"连接超时\")
except http.client.InvalidURL:
print(\"无效的 URL\")
except Exception as e:
print(f\"发生错误: {e}\")
finally:
if conn:
conn.close()
7. 完整示例:获取天气 API 数据
import http.client
import json
try:
# 连接到天气API
conn = http.client.HTTPSConnection(\"api.openweathermap.org\")
# API参数(城市ID和API密钥)
city_id = \"1850147\" # 东京的城市ID
api_key = \"YOUR_API_KEY\" # 替换为你的API密钥
# 发送请求
conn.request(\"GET\", f\"/data/2.5/weather?id={city_id}&appid={api_key}\")
# 获取响应
response = conn.getresponse()
if response.status == 200:
data = json.loads(response.read().decode())
print(f\"城市: {data[\'name\']}\")
print(f\"天气: {data[\'weather\'][0][\'description\']}\")
print(f\"温度: {data[\'main\'][\'temp\'] - 273.15:.1f}°C\") # 转为摄氏度
else:
print(f\"错误: {response.status} - {response.read().decode()}\")
except Exception as e:
print(f\"发生异常: {e}\")
finally:
conn.close()
8. 与 requests 库对比
特性
http.client
requests
所属库
Python 标准库(无需安装)
第三方库(需 pip install)
API 复杂度
底层,需要手动处理很多细节
高层,简洁易用
请求方法
request() 结合方法参数
get(), post(), put() 等
响应处理
手动解析状态码、头和内容
自动解析,提供 json() 方法
会话管理
需手动管理连接
自动管理会话(如 Cookie)
重定向处理
需手动实现
自动处理(可配置)
文件上传
复杂
简单(files 参数)
9. 常见问题解答
- Q1:如何设置请求超时?
A:在创建连接时指定 timeout 参数,如 HTTPSConnection(\"example.com\", timeout=10)。
- Q2:如何处理 HTTPS 证书验证?
A:默认验证证书。若需忽略,使用 context 参数:
import ssl
context = ssl._create_unverified_context()
conn = http.client.HTTPSConnection(\"example.com\", context=context)
- Q3:如何发送大文件?
A:使用分块传输(Chunked Transfer),需设置 Transfer-Encoding: chunked 头,手动分块发送。
通过这个教程,你应该能够掌握 http.client 的基本使用方法。在实际项目中,若追求更高的开发效率,推荐使用 requests 库;若需要底层控制或环境受限(如无第三方库),则 http.client 是更好的选择。