Python requests详解:从入门到实战,HTTP请求的“瑞士军刀”

在网络爬虫、API调用、接口测试等场景中,发送HTTP请求是核心需求。Python的requests库以其简洁的API、强大的功能和人性化的设计,成为处理HTTP请求的首选工具------相比Python内置的urllib,它省去了繁琐的编码和解码步骤,让开发者能更专注于业务逻辑。本文将从基础用法→核心功能→实战案例→避坑指南 ,全方位带你掌握requests,轻松应对各类网络请求场景。

一、什么是requests?为什么选择它?

requests是Python的一个第三方HTTP库,由Kenneth Reitz开发,遵循"简单优雅"的设计哲学。它封装了底层的网络通信细节,提供了直观的API,让发送HTTP请求变得像调用函数一样简单。

为什么requests是处理HTTP的最佳选择?

  • 简洁易用:一行代码即可发送GET/POST请求,无需手动处理URL编码、Cookie管理等细节;
  • 功能全面:支持GET、POST、PUT、DELETE等所有HTTP方法,以及会话保持、文件上传、代理设置等高级功能;
  • 自动处理细节:自动解析JSON响应、处理gzip压缩、管理连接池,减少开发者的重复劳动;
  • 活跃的社区 :文档完善(官方文档),问题解决方案丰富,遇到问题能快速找到答案。

举个直观的例子:用urllib发送一个带参数的GET请求需要5行代码处理编码和请求,而用requests只需1行------这就是requests的魅力。

二、安装与导入:5分钟上手准备

1. 安装requests

requests不是Python标准库,需用pip安装:

bash 复制代码
pip install requests  # 基础安装,支持所有核心功能

2. 导入requests

使用时直接导入即可,无需复杂配置:

python 复制代码
import requests  # 导入库

三、核心功能:发送HTTP请求

HTTP请求的核心是"方法+URL+参数+头部信息",requests为每种HTTP方法都提供了对应的函数(如requests.get()requests.post()),用法高度统一。

1. GET请求:获取资源(最常用)

GET请求用于从服务器获取资源(如网页内容、API数据),参数通常通过URL的查询字符串(?key=value&key2=value2)传递。

(1)基础GET请求
python 复制代码
# 发送GET请求到百度首页
url = "https://www.baidu.com"
response = requests.get(url)  # 返回一个Response对象

# 查看响应基本信息
print("状态码:", response.status_code)  # 200表示成功
print("响应头部:", response.headers)    # 字典形式的响应头
print("编码方式:", response.encoding)   # 自动识别的编码(如'ISO-8859-1')
print("网页内容(前500字符):", response.text[:500])  # 文本形式的响应体
(2)带参数的GET请求

通过params参数传递查询字符串,无需手动拼接URL(requests会自动编码特殊字符):

python 复制代码
# 示例:调用天气API(模拟,实际需替换为真实API)
url = "https://api.weather.com/query"
params = {
    "city": "北京",  # 城市名
    "key": "abc123",  # API密钥
    "format": "json"  # 返回格式
}

# 发送带参数的GET请求
response = requests.get(url, params=params)

# 查看实际请求的URL(自动拼接了参数)
print("实际请求URL:", response.url)  # 输出:https://api.weather.com/query?city=北京&key=abc123&format=json

# 解析JSON响应(API通常返回JSON)
if response.status_code == 200:  # 200表示请求成功
    data = response.json()  # 自动解析JSON,返回字典/列表
    print("天气数据:", data)
else:
    print(f"请求失败,状态码:{response.status_code}")

关键说明

  • response.text:返回字符串形式的响应体(适用于HTML、纯文本);
  • response.json():自动解析JSON格式的响应体(适用于API),若响应不是JSON会抛JSONDecodeError
  • response.content:返回字节形式的响应体(适用于图片、二进制文件)。

2. POST请求:提交数据

POST请求用于向服务器提交数据(如表单提交、API数据上传),数据通常放在请求体中(而非URL),更安全且支持更大的数据量。

(1)提交表单数据(application/x-www-form-urlencoded

data参数传递表单数据(字典形式):

python 复制代码
# 示例:模拟登录表单提交(模拟URL,非真实接口)
url = "https://example.com/login"
data = {
    "username": "test_user",
    "password": "test_pass123",
    "remember_me": "1"
}

# 发送POST请求,提交表单数据
response = requests.post(url, data=data)

print("登录响应:", response.text)
(2)提交JSON数据(application/json

API接口通常要求提交JSON格式数据,用json参数直接传递Python字典(requests会自动序列化并设置Content-Type: application/json):

python 复制代码
# 示例:调用创建用户的API(模拟)
url = "https://api.example.com/users"
user_data = {
    "name": "张三",
    "age": 25,
    "email": "zhangsan@example.com"
}

# 发送POST请求,提交JSON数据
response = requests.post(url, json=user_data)  # 自动处理JSON序列化

if response.status_code == 201:  # 201表示资源创建成功
    print("用户创建成功:", response.json())
else:
    print("创建失败:", response.text)

3. 其他HTTP方法

requests支持所有HTTP标准方法,用法与GET/POST一致:

  • requests.put(url, data=...):更新资源(全量更新);
  • requests.patch(url, data=...):部分更新资源;
  • requests.delete(url):删除资源;
  • requests.head(url):只获取响应头(无响应体);
  • requests.options(url):获取服务器支持的HTTP方法。

示例:删除资源

python 复制代码
url = "https://api.example.com/users/123"
response = requests.delete(url)
if response.status_code == 204:  # 204表示删除成功(无响应体)
    print("用户删除成功")

四、进阶功能:应对复杂场景

实际开发中,HTTP请求往往需要处理 headers、Cookies、代理等细节,requests提供了完善的支持。

1. 设置请求头(Headers)

服务器通常通过User-Agent识别客户端类型(如浏览器、爬虫),若不设置可能被拒绝访问(反爬机制)。用headers参数自定义请求头:

python 复制代码
url = "https://www.example.com"

# 模拟浏览器请求头(从浏览器开发者工具中复制)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Referer": "https://www.google.com/"  # 防盗链:表示从谷歌跳转过来
}

response = requests.get(url, headers=headers)
print("响应状态码:", response.status_code)  # 200表示成功(若不设headers可能返回403)

2. 处理Cookies

Cookies用于维持会话状态(如登录状态),requests会自动处理响应中的Cookies,并在后续请求中携带。

(1)自动管理Cookies
python 复制代码
# 步骤1:登录(服务器返回Cookies)
login_url = "https://example.com/login"
data = {"username": "user", "password": "pass"}
response = requests.post(login_url, data=data)

# 步骤2:访问需要登录的页面(自动携带登录后的Cookies)
profile_url = "https://example.com/profile"
response = requests.get(profile_url)  # 无需手动传递Cookies
print("个人信息页面:", response.text)
(2)手动设置Cookies

若需手动控制Cookies,可通过cookies参数传递字典:

python 复制代码
url = "https://example.com"
cookies = {"user_id": "123", "session": "abcdef123456"}
response = requests.get(url, cookies=cookies)

3. 设置超时时间(Timeout)

若服务器无响应,程序会一直阻塞,用timeout参数设置超时时间(单位:秒):

python 复制代码
url = "https://www.example.com"
try:
    # 3秒内未收到响应则超时
    response = requests.get(url, timeout=3)
    print("请求成功")
except requests.exceptions.Timeout:
    print("请求超时(3秒内未响应)")
except requests.exceptions.RequestException as e:  # 捕获其他请求异常
    print(f"请求失败:{e}")

4. 使用代理(Proxies)

爬取数据时,频繁请求可能导致IP被封,用代理IP隐藏真实IP:

python 复制代码
url = "https://www.example.com"

# 代理配置(HTTP和HTTPS代理)
proxies = {
    "http": "http://123.45.67.89:8080",  # HTTP代理
    "https": "https://123.45.67.89:8080"  # HTTPS代理
}

# 发送带代理的请求
response = requests.get(url, proxies=proxies)
print("响应状态码:", response.status_code)

注意:实际使用需替换为有效的代理IP(可从代理服务商获取)。

5. 会话保持(Session)

requests.Session()创建会话对象,能在多个请求间保持Cookies、headers等状态,适合需要连续操作的场景(如登录→浏览→下单):

python 复制代码
# 创建会话对象
session = requests.Session()

# 1. 登录(会话会保存Cookies)
login_url = "https://example.com/login"
session.post(login_url, data={"username": "user", "password": "pass"})

# 2. 访问个人中心(自动携带登录Cookies)
profile_url = "https://example.com/profile"
response = session.get(profile_url)
print("个人中心内容:", response.text)

# 3. 退出登录
logout_url = "https://example.com/logout"
session.get(logout_url)

# 关闭会话(可选)
session.close()

6. 文件上传

files参数上传文件(适用于multipart/form-data类型的表单):

python 复制代码
url = "https://example.com/upload"

# 准备上传的文件(打开文件时用二进制模式"rb")
files = {
    "file": open("test.jpg", "rb"),  # "file"是表单字段名
    "description": ("", "这是一张测试图片", "text/plain")  # 额外的文本字段
}

response = requests.post(url, files=files)
print("上传结果:", response.text)

# 记得关闭文件(或用with语句)
files["file"].close()

五、实战案例:爬取豆瓣电影TOP250

requests爬取豆瓣电影TOP250的名称、评分和引言,展示完整的网络请求+数据提取流程(需配合简单的字符串处理,实际爬虫可结合BeautifulSoup解析HTML)。

python 复制代码
import requests
import re  # 用正则提取数据(简化示例,实际推荐BeautifulSoup)

# 豆瓣电影TOP250第一页URL
url = "https://movie.douban.com/top250"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

try:
    # 发送请求
    response = requests.get(url, headers=headers, timeout=5)
    response.raise_for_status()  # 若状态码不是200,抛HTTPError
    response.encoding = "utf-8"  # 手动指定编码(解决部分网站乱码)

    # 用正则提取电影信息(简化示例)
    # 匹配电影名称:<span class="title">肖申克的救赎</span>
    titles = re.findall(r'<span class="title">([^&]*?)</span>', response.text)
    # 匹配评分:<span class="rating_num" property="v:average">9.7</span>
    ratings = re.findall(r'<span class="rating_num" property="v:average">([0-9.]+)</span>', response.text)
    # 匹配引言:<span class="inq">希望让人自由。</span>
    quotes = re.findall(r'<span class="inq">(.*?)</span>', response.text)

    # 打印结果(前5部)
    print("豆瓣电影TOP250(前5部):")
    for i in range(5):
        print(f"{i+1}. 电影名:{titles[i]},评分:{ratings[i]},引言:{quotes[i]}")

except requests.exceptions.HTTPError as e:
    print(f"HTTP错误:{e}")
except requests.exceptions.RequestException as e:
    print(f"请求失败:{e}")

输出结果

复制代码
豆瓣电影TOP250(前5部):
1. 电影名:肖申克的救赎,评分:9.7,引言:希望让人自由。
2. 电影名:霸王别姬,评分:9.6,引言:风华绝代。
3. 电影名:阿甘正传,评分:9.5,引言:一部美国近现代史。
4. 电影名:泰坦尼克号,评分:9.4,引言:失去的才是永恒的。
5. 电影名:这个杀手不太冷,评分:9.4,引言:怪蜀黍和小萝莉 的纯粹爱情。

六、避坑指南:requests常见错误及解决

1. 中文乱码问题

问题response.text返回的内容中文乱码。
原因requests自动识别的编码(response.encoding)与网页实际编码不一致。
解决 :手动指定正确编码(如utf-8gbk):

python 复制代码
response = requests.get(url)
response.encoding = "utf-8"  # 强制设置编码为utf-8
print(response.text)

2. 被反爬机制拦截(403 Forbidden)

问题 :请求返回403,提示"拒绝访问"。
原因 :服务器识别出爬虫(如缺少User-Agent、请求频率过高)。
解决

  • 设置真实的User-Agent(模拟浏览器);
  • 降低请求频率(加time.sleep(1));
  • 使用代理IP;
  • 携带Referer头(模拟从合法页面跳转)。

3. JSON解析失败(JSONDecodeError)

问题response.json()JSONDecodeError
原因 :响应内容不是JSON格式(如HTML、错误信息)。
解决 :先检查状态码,非200时用response.text查看错误信息:

python 复制代码
response = requests.get(url)
if response.status_code == 200:
    try:
        data = response.json()
    except json.JSONDecodeError:
        print("响应不是JSON:", response.text)
else:
    print("请求失败:", response.text)

4. 大文件下载内存溢出

问题 :下载大文件(如1GB视频)时,response.content会将整个文件加载到内存,导致溢出。
解决 :用stream=True流式下载,分块写入磁盘:

python 复制代码
url = "https://example.com/large_file.zip"
with requests.get(url, stream=True) as response:
    with open("file.zip", "wb") as f:
        for chunk in response.iter_content(chunk_size=1024*1024):  # 每次1MB
            if chunk:  # 过滤空块
                f.write(chunk)
print("下载完成")

5. 忽略SSL证书验证错误

问题 :访问HTTPS网站时,因证书无效抛SSLError
解决 :开发环境可临时设置verify=False(生产环境不推荐,有安全风险):

python 复制代码
response = requests.get("https://self-signed.example.com", verify=False)

七、总结:requests是网络请求的最佳拍档

requests的核心价值在于 "化繁为简" ------它将复杂的HTTP协议细节封装成直观的API,让开发者无需关注底层实现,只需专注于"发送什么请求"和"如何处理响应"。无论是简单的网页爬取、API调用,还是复杂的会话管理、文件上传,requests都能轻松应对。

学习建议:

  1. 熟练掌握基础方法 :GET/POST是核心,务必理解paramsdatajson参数的区别;
  2. 重视异常处理 :网络请求充满不确定性,用try-except捕获RequestException及子类异常;
  3. 模拟浏览器行为:处理反爬时,学会复制真实请求的headers、Cookies;
  4. 结合解析库使用 :爬取网页时,requests配合BeautifulSoup(解析HTML)或lxml(高效解析),能大幅提升效率;
  5. 查阅官方文档requests功能丰富,官方文档是最好的学习资料。

掌握requests后,你会发现网络请求不再是难题------从调用开放API获取数据,到开发简单的爬虫收集信息,再到测试自己的后端接口,它都能成为你的得力助手。

相关推荐
深度学习lover4 小时前
<数据集>yolo螺丝螺母识别数据集<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·螺丝螺母识别
Geoking.4 小时前
PyTorch 基础详解:tensor.item() 方法
人工智能·pytorch·python
ZIM学编程4 小时前
「学长有话说」作为一个大三学长,我想对大一计算机专业学生说这些!
java·c语言·数据结构·c++·python·学习·php
没有钱的钱仔4 小时前
conda 基础命令使用
python
程序员三藏4 小时前
如何使用Selenium做自动化测试?
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
Python私教5 小时前
基于 Django 5 + DRF 构建博客系统后端接口(从建模到接口实现)
python·django·sqlite
南方的狮子先生5 小时前
【深度学习】60 分钟 PyTorch 极速入门:从 Tensor 到 CIFAR-10 分类
人工智能·pytorch·python·深度学习·算法·分类·1024程序员节
闲人编程6 小时前
Docker化你的Python应用:从开发到生产
python·docker·eureka·开发·生产·codecapsule
JJJJ_iii6 小时前
【机器学习10】项目生命周期、偏斜类别评估、决策树
人工智能·python·深度学习·算法·决策树·机器学习