最简洁的 Python HTTP 请求库使用指南


1. 安装与导入

安装 requests

pip install requests

导入模块

import requests

2. GET 请求

GET 请求用于从服务器获取数据,参数通过 URL 传递。

基础用法

import requests

# 最简单的 GET 请求
response = requests.get("https://api.github.com")
print(response.status_code)  # 200
print(response.text)         # 响应内容(字符串)

带参数的 GET 请求

import requests

# 方式1:直接拼接 URL(不推荐)
url = "https://httpbin.org/get?name=john&age=25"
response = requests.get(url)

# 方式2:使用 params 参数(推荐)
params = {
    "name": "john",
    "age": 25,
    "city": "beijing"
}
response = requests.get("https://httpbin.org/get", params=params)
print(response.url)  # https://httpbin.org/get?name=john&age=25&city=beijing

设置请求头(Headers)

import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.0",
    "Accept": "application/json",
    "Authorization": "Bearer your_token_here"  # 如果需要认证
}

response = requests.get("https://httpbin.org/get", headers=headers)

获取 JSON 数据

import requests

response = requests.get("https://api.github.com/users/github")
data = response.json()  # 直接解析为 Python 字典

print(data["login"])      # github
print(data["public_repos"])  # 公开仓库数量

GET 请求完整示例

import requests

def fetch_weather(city):
    """获取天气信息示例"""
    url = "https://api.example.com/weather"
    params = {"city": city}
    headers = {
        "User-Agent": "MyWeatherApp/1.0",
        "Accept": "application/json"
    }

    try:
        response = requests.get(url, params=params, headers=headers, timeout=10)
        response.raise_for_status()  # 检查 HTTP 错误
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None

# 使用
weather = fetch_weather("beijing")
if weather:
    print(f"温度: {weather.get('temperature')}°C")

3. POST 请求

POST 请求用于向服务器提交数据,常用于表单提交、文件上传等。

基础用法

import requests

# 最简单的 POST 请求
response = requests.post("https://httpbin.org/post")
print(response.status_code)

提交表单数据(form-data)

import requests

# 模拟登录表单
login_data = {
    "username": "john",
    "password": "secret123"
}

response = requests.post(
    "https://httpbin.org/post",
    data=login_data  # 使用 data 参数
)

提交 JSON 数据

import requests

user_data = {
    "name": "张三",
    "age": 25,
    "email": "zhangsan@example.com"
}

response = requests.post(
    "https://httpbin.org/post",
    json=user_data  # 使用 json 参数,自动设置 Content-Type: application/json
)

# 等同于:
# response = requests.post(
#     url,
#     data=json.dumps(user_data),
#     headers={"Content-Type": "application/json"}
# )

POST 请求完整示例

import requests

def create_user(name, email):
    """创建用户示例"""
    url = "https://api.example.com/users"

    payload = {
        "name": name,
        "email": email,
        "role": "user"
    }

    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer your_api_token"
    }

    try:
        response = requests.post(url, json=payload, headers=headers, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"创建用户失败: {e}")
        return None

# 使用
result = create_user("李四", "lisi@example.com")
if result:
    print(f"用户创建成功,ID: {result.get('id')}")

4. GET vs POST 对比

特性GETPOST
用途获取数据提交数据
参数位置URL 查询参数请求体 (body)
数据大小受 URL 长度限制(约 2KB)无限制
安全性参数暴露在 URL 中参数在请求体中,相对安全
缓存会被浏览器缓存不会被缓存
书签可以收藏不能收藏
幂等性幂等(多次请求结果相同)非幂等(可能创建多条记录)

使用建议

# GET:获取数据、搜索、分页
requests.get("/api/users?page=1")
requests.get("/api/search?q=python")

# POST:创建资源、登录、提交表单
requests.post("/api/users", json={"name": "john"})
requests.post("/api/login", data={"user": "john", "pass": "xxx"})

5. 响应对象详解

import requests

response = requests.get("https://httpbin.org/get")

# 状态码
print(response.status_code)       # 200
print(response.ok)                # True (200-299 为 True)

# 响应内容
print(response.text)              # 字符串形式
print(response.content)           # 二进制形式(用于图片、文件等)
print(response.json())            # JSON 解析为字典

# 响应头
print(response.headers)           # 所有响应头
print(response.headers["Content-Type"])

# 编码
print(response.encoding)          # 自动检测的编码,如 utf-8
response.encoding = "utf-8"       # 手动设置编码

# URL 信息
print(response.url)               # 最终请求的 URL(包含重定向)
print(response.history)           # 重定向历史

6. 错误处理

import requests
from requests.exceptions import (
    RequestException,
    HTTPError,
    ConnectionError,
    Timeout,
    URLRequired,
    TooManyRedirects
)

def safe_request(url, method="get", **kwargs):
    """安全的 HTTP 请求封装"""
    try:
        if method.lower() == "post":
            response = requests.post(url, **kwargs)
        else:
            response = requests.get(url, **kwargs)

        # 检查 HTTP 错误(4xx, 5xx)
        response.raise_for_status()
        return response

    except ConnectionError:
        print(f"连接错误:无法连接到 {url}")
    except Timeout:
        print(f"请求超时:{url}")
    except HTTPError as e:
        print(f"HTTP 错误:{e}")
    except TooManyRedirects:
        print(f"重定向次数过多:{url}")
    except RequestException as e:
        print(f"请求异常:{e}")

    return None

# 使用
response = safe_request("https://api.example.com/data", timeout=5)
if response:
    print(response.json())

7. 常用配置

超时设置

# 总超时时间
response = requests.get(url, timeout=5)

# 分别设置连接超时和读取超时
response = requests.get(url, timeout=(3, 27))  # 连接3秒,读取27秒

代理设置

proxies = {
    "http": "http://10.10.1.10:3128",
    "https": "http://10.10.1.10:1080",
}

response = requests.get(url, proxies=proxies)
# 使用 Session 保持会话状态
session = requests.Session()

# 登录
session.post("https://example.com/login", data={"user": "john", "pass": "xxx"})

# 后续请求自动携带 Cookie
response = session.get("https://example.com/profile")

8. 完整实战示例

import requests

class APIClient:
    """简单的 API 客户端封装"""

    def __init__(self, base_url, token=None):
        self.base_url = base_url
        self.session = requests.Session()
        if token:
            self.session.headers.update({
                "Authorization": f"Bearer {token}"
            })

    def get(self, endpoint, params=None):
        """GET 请求"""
        url = f"{self.base_url}{endpoint}"
        response = self.session.get(url, params=params, timeout=10)
        response.raise_for_status()
        return response.json()

    def post(self, endpoint, data=None, json=None):
        """POST 请求"""
        url = f"{self.base_url}{endpoint}"
        response = self.session.post(url, data=data, json=json, timeout=10)
        response.raise_for_status()
        return response.json()

# 使用示例
client = APIClient("https://api.example.com", token="your_token")

# GET 请求
users = client.get("/users", params={"page": 1, "limit": 10})
print(f"获取到 {len(users)} 个用户")

# POST 请求
new_user = client.post("/users", json={"name": "王五", "email": "wangwu@example.com"})
print(f"新用户 ID: {new_user['id']}")

参考