Python requests库教程:从GET请求到Session会话管理完整指南

📝 974 字 · ☕ 3 分钟阅读

Python requests库教程:从GET请求到Session会话管理完整指南

前言:为什么你需要学习requests库

在Python生态中,requests库是最受欢迎的HTTP客户端库,没有之一。无论是调用REST API、爬取网页数据、与云服务交互,还是搭建自动化脚本,requests都是必选项。Python官方文档甚至称其为”HTTP for Humans”——专为人类设计的HTTP库。

但很多初学者只会用 requests.get() 获取页面内容,遇到需要登录、设置请求头、处理Session会话时就卡住了。本文将带你从零开始,系统掌握requests库的核心用法:从最基础的GET/POST请求,到Cookie自动管理、Session会话保持、请求头自定义、超时重试、以及错误处理。读完本文,你就能用requests搞定日常开发中99%的HTTP请求场景。

环境准备

  • Python版本: 3.7+(推荐Python 3.10及以上)
  • requests库版本: 2.31+(2026年最新稳定版)
  • 系统: Windows / macOS / Linux 均可

安装requests库

pip install requests

验证安装:

$ python -c "import requests; print(requests.__version__)"
2.32.3

步骤一:发送GET请求获取数据

GET请求是最常见的HTTP请求方式,用于从服务器获取资源。以下是一个最简单的例子——获取一个JSON格式的公开API数据:

import requests

# 请求一个公开的JSON API
url = "https://api.github.com/repos/psf/requests"
response = requests.get(url)

# 检查响应状态码
print(f"状态码: {response.status_code}")

# 将响应解析为JSON
data = response.json()
print(f"仓库名: {data['full_name']}")
print(f"Star数: {data['stargazers_count']}")
print(f"描述: {data['description']}")

输出示例:

状态码: 200
仓库名: psf/requests
Star数: 53000+
描述: A simple, yet elegant, HTTP library.

GET请求带参数

很多API需要在URL后附加查询参数。requests的 params 参数能帮你优雅地构建URL:

import requests

# 不用手动拼接 URL,用 params 字典
params = {
    "q": "requests",
    "sort": "stars",
    "order": "desc",
    "per_page": 5
}
url = "https://api.github.com/search/repositories"
response = requests.get(url, params=params)

# requests 自动将 params 编码到 URL
print(f"请求的完整URL: {response.url}")
# 输出: https://api.github.com/search/repositories?q=requests&sort=stars&order=desc&per_page=5

data = response.json()
for repo in data["items"]:
    print(f"⭐ {repo['full_name']} — {repo['stargazers_count']} stars")

使用 params 的好处:requests会自动处理URL编码(比如中文、特殊符号),避免手动拼接时出错。

步骤二:设置请求头(Headers)

很多API要求客户端在请求头中传递认证信息、指定内容类型或模拟浏览器行为。通过 headers 参数可以轻松设置:

import requests

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

url = "https://api.github.com/user"
response = requests.get(url, headers=headers)

if response.status_code == 200:
    print("认证成功!")
    print(f"用户: {response.json()['login']}")
elif response.status_code == 401:
    print("认证失败,请检查Token")

常见请求头说明:

请求头 作用
User-Agent 标识客户端类型,很多网站会拦截默认的 “python-requests”
Authorization 携带认证令牌(Bearer Token / Basic Auth)
Content-Type 指定请求体格式(如 application/json)
Accept 告诉服务器客户端期望的响应格式
Cookie 携带会话Cookie(通常用Session对象自动管理)

步骤三:发送POST请求提交数据

POST请求用于向服务器提交数据,比如用户登录、创建资源、提交表单等。requests根据提交的数据类型,提供了不同的参数:

3.1 提交JSON数据

使用 json 参数,requests会自动设置 Content-Type: application/json

import requests

url = "https://jsonplaceholder.typicode.com/posts"
new_post = {
    "title": "Python requests 教程",
    "body": "这是一篇关于requests库的教程",
    "userId": 1
}

response = requests.post(url, json=new_post)
print(f"状态码: {response.status_code}")  # 201 Created
print(f"创建的资源ID: {response.json()['id']}")

3.2 提交表单数据

使用 data 参数模拟HTML表单提交:

import requests

url = "https://httpbin.org/post"
form_data = {
    "username": "test_user",
    "password": "test_pass123"
}

response = requests.post(url, data=form_data)
print(response.json()["form"])
# 输出: {'username': 'test_user', 'password': 'test_pass123'}

3.3 上传文件

import requests

url = "https://httpbin.org/post"
files = {
    "file": ("report.txt", "这是文件内容", "text/plain")
}

response = requests.post(url, files=files)
print(response.json()["files"])
# 输出: {'file': '这是文件内容'}

步骤四:管理Session和Cookie

这是日常开发中最重要的技能之一。Session对象可以在多个请求之间自动保持Cookie,让你像浏览器一样维持登录状态。

4.1 为什么需要Session?

每次调用 requests.get()requests.post() 都是独立的请求,不会自动携带之前请求返回的Cookie。如果连续调用一个需要登录的API,每次都要手动传递Cookie,非常麻烦。

requests.Session() 帮你自动搞定这一切:

4.2 Session基础用法

import requests

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

# 设置全局请求头(所有会话中的请求都会自动带上)
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})

# 第一次请求——模拟登录(服务器返回Cookie)
login_url = "https://httpbin.org/cookies/set/sessionid/abc123"
response = session.get(login_url)
print(f"登录响应: {response.json()}")

# 第二次请求——Session自动携带了Cookie
check_url = "https://httpbin.org/cookies"
response = session.get(check_url)
print(f"当前Cookie: {response.json()}")
# 输出: {'cookies': {'sessionid': 'abc123'}}

# 使用同一个Session,Cookie自动保持

4.3 真实场景:登录网站后保持会话

import requests

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})

# 步骤1:先访问登录页面获取CSRF Token(实际开发中常见)
login_page_url = "https://example.com/login"
page_resp = session.get(login_page_url)
# 从HTML中解析CSRF Token(省略正则/BeautifulSoup代码)

# 步骤2:提交登录表单
login_data = {
    "username": "your_username",
    "password": "your_password",
    "csrf_token": "extracted_token"
}
login_resp = session.post(login_page_url, data=login_data)

if login_resp.ok:
    print("登录成功!")

# 步骤3:访问需要登录的页面——Session自动携带认证Cookie
dashboard_url = "https://example.com/dashboard"
dashboard_resp = session.get(dashboard_url)
print(f"已登录用户页面状态码: {dashboard_resp.status_code}")

4.4 手动添加Cookie

如果你已经有了Cookie字符串,可以直接注入到Session中:

import requests

session = requests.Session()

# 方式一:更新Cookie字典
session.cookies.update({
    "sessionid": "abc123",
    "token": "xyz789"
})

# 方式二:从响应中提取并设置
response = requests.get("https://httpbin.org/cookies/set/foo/bar")
for cookie in response.cookies:
    session.cookies.set(cookie.name, cookie.value)

# 验证
resp = session.get("https://httpbin.org/cookies")
print(resp.json())

步骤五:超时、重试与错误处理

网络请求必须考虑异常情况,否则你的程序会在网络波动时直接崩溃。

5.1 设置超时

永远不要不设置超时!不设超时的请求可能无限等待:

import requests
from requests.exceptions import Timeout

try:
    # timeout = (connect_timeout, read_timeout)
    response = requests.get("https://httpbin.org/delay/10", timeout=(3, 5))
    print(response.text)
except Timeout:
    print("请求超时!")

5.2 连接错误处理

import requests
from requests.exceptions import ConnectionError, Timeout, RequestException

url = "https://api.example.com/data"
try:
    response = requests.get(url, timeout=10)
    response.raise_for_status()  # 非200状态码会抛出HTTPError
    data = response.json()
    print("请求成功:", data)
except ConnectionError:
    print(f"无法连接到 {url},请检查网络或域名")
except Timeout:
    print(f"请求 {url} 超时")
except requests.exceptions.HTTPError as e:
    print(f"HTTP错误: {e.response.status_code}")
except RequestException as e:
    print(f"请求异常: {e}")

5.3 自动重试机制

使用 requests.adapters.HTTPAdapter 结合Session实现自动重试:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 创建Session
session = requests.Session()

# 配置重试策略
retry_strategy = Retry(
    total=3,               # 最多重试3次
    backoff_factor=1,      # 退避因子:重试间隔 = {backoff_factor} * (2^({retry_number} - 1))
    status_forcelist=[500, 502, 503, 504],  # 这些状态码触发重试
    allowed_methods=["GET", "POST"]  # 哪些方法可以重试
)

# 将重试策略挂载到HTTP适配器
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)

# 现在这个Session会自动重试失败的请求
response = session.get("https://httpbin.org/status/500", timeout=10)
print(f"最终状态码: {response.status_code}")

完整实战:用requests抓取GitHub Trending仓库

下面是一个综合示例,综合运用了本文提到的所有知识点:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from requests.exceptions import RequestException
from datetime import datetime

def create_robust_session():
    """创建一个带重试机制的Session"""
    session = requests.Session()
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "Accept": "application/vnd.github.v3+json"
    })

    retry_strategy = Retry(
        total=3,
        backoff_factor=0.5,
        status_forcelist=[429, 500, 502, 503, 504]
    )
    adapter = HTTPAdapter(max_retries=retry_strategy)
    session.mount("https://", adapter)
    return session

def get_trending_repositories():
    """获取GitHub每日热门仓库"""
    session = create_robust_session()

    params = {
        "q": "created:>2026-05-01",
        "sort": "stars",
        "order": "desc",
        "per_page": 10
    }

    try:
        response = session.get(
            "https://api.github.com/search/repositories",
            params=params,
            timeout=15
        )
        response.raise_for_status()
        data = response.json()

        print(f"🔥 GitHub热门仓库 ({datetime.now().strftime('%Y-%m-%d')}):\n")
        for i, repo in enumerate(data["items"], 1):
            print(f"{i}. {repo['full_name']}")
            print(f"   ⭐ Stars: {repo['stargazers_count']}")
            print(f"   📝 描述: {repo['description'] or '无描述'}")
            print(f"   🔗 {repo['html_url']}\n")

    except RequestException as e:
        print(f"获取数据失败: {e}")

if __name__ == "__main__":
    get_trending_repositories()

常见问题(FAQ)

Q1: requests.get() 返回的状态码不是200怎么办?

首先用 response.status_code 查看具体状态码。常见情况:401 Unauthorized — 需要添加认证信息(Token/Auth);403 Forbidden — IP被限制或需要添加合适的 User-Agent;404 Not Found — URL路径或参数有误;429 Too Many Requests — 请求频率过高,需要添加延时或使用重试机制;5xx — 服务端问题,可以重试。建议始终调用 response.raise_for_status() 来主动抛出异常。

Q2: requests.Session() 和直接调用 requests.get() 有什么区别?

核心区别在于连接复用和Cookie自动管理。直接调用 requests.get() 每次都会创建新的连接,不会自动携带之前请求返回的Cookie。而 requests.Session() 会复用TCP连接(减少连接建立开销),并在同一Session内的所有请求中自动保持Cookie。如果需要连续调用同一个站点的多个API、或者需要登录后保持会话,务必使用Session。

Q3: requests 和 urllib 应该用哪个?

无脑选requests。Python内置的 urllib 虽然功能齐全,但API设计繁琐:需要用 urlopen、手动处理编码、手动管理Cookie、手动处理异常。而requests API简洁直观,一个 get() / post() 就能搞定大部分场景,代码量减少50%以上。requests底层其实也使用了urllib3,但上层API做了大量人性化封装。只有在完全不能安装第三方库的受限环境中才考虑使用urllib。

Q4: 如何解决 ‘SSL: CERTIFICATE_VERIFY_FAILED’ 证书验证错误?

首先检查系统时间是否正确(证书过期检测依赖正确时间)。如果是自签名证书或测试环境,可以设置 verify=False 跳过验证(同时要用 urllib3.disable_warnings() 关闭警告):requests.get(url, verify=False)。生产环境建议正确配置CA证书,或指定证书路径:requests.get(url, verify='/path/to/cert.pem')

如果你正在寻找更专业的 API 调试工具,不妨看看我们的 2026年最好用的5个免费API测试工具评测,找到最适合你的 Postman 替代品。

总结

本文从零开始,系统学习了Python requests库的核心用法:

  • GET请求:基础获取数据 + params参数传递
  • 请求头设置:User-Agent、Authorization等关键头部配置
  • POST请求:提交JSON数据、表单数据、文件上传
  • Session会话管理:Cookie自动保持、登录状态维持
  • 错误处理:超时设置、连接错误捕获、自动重试机制

requests库是Python开发者工具箱中最重要的武器之一,建议将本文的代码保存为参考模板,在实际项目中直接复用。

📖 推荐阅读:

📤 分享这篇文章