pin_drop当前位置:知识文库 ❯ 图文

requests文件上传下载教程 - 流式下载与files参数详解

一、文件上传下载概述

requests库支持文件上传和下载功能。文件上传通过files参数实现,支持单文件和多文件上传,自动处理multipart/form-data编码。文件下载通过Response对象的content属性获取二进制数据,支持流式下载大文件。这两个功能在Web开发、自动化测试和数据处理中非常常用。

二、文件上传语法与参数

代码示例

# 文件上传
requests.post(url, files={'field': ('filename', file_obj, 'content_type')})

# 文件下载
response = requests.get(url, stream=True)
with open('filename', 'wb') as f:
    for chunk in response.iter_content(chunk_size=8192):
        f.write(chunk)

文件上传files参数格式

格式 示例 说明
文件对象 {'file': open('data.txt', 'rb')} 最简形式
带文件名 {'file': ('data.txt', open('data.txt', 'rb'))} 指定上传文件名
带文件名和类型 {'file': ('data.txt', open('data.txt', 'rb'), 'text/plain')} 指定Content-Type
多文件上传 {'files': [('f1', open('a.txt', 'rb')), ('f2', open('b.txt', 'rb'))]} 同一字段多文件

文件下载相关参数

参数 类型 默认值 说明
stream bool False True时延迟下载响应体,适合大文件
iter_content(chunk_size) method - 按指定大小迭代读取响应内容

三、单文件上传

使用io.BytesIO可以在内存中构建文件内容进行上传,非常适合不需要读取磁盘文件的场景。

代码示例

import requests
import io

# 方式1:上传内存中的文件内容
file_content = b'Hello, this is file content for upload!'
files = {'file': ('test.txt', io.BytesIO(file_content), 'text/plain')}

response = requests.post('https://httpbin.org/post', files=files)
result = response.json()

print(f"上传状态码: {response.status_code}")
print(f"服务器收到文件名: {result['files']['file'][:30]}...")
print(f"Content-Type: {result['headers'].get('Content-Type', '')[:40]}...")

输出结果:

代码示例

上传状态码: 200
服务器收到文件名: Hello, this is file content for uploa...
Content-Type: multipart/form-data; boundary=---...

四、多文件上传与表单混合

在实际应用中,经常需要同时上传文件和提交表单数据。requests允许同时传递filesdata参数。

代码示例

import requests
import io

# 同时上传文件和提交表单数据
files = {
    'document': ('report.csv', io.BytesIO(b'id,name,score\n1,Alice,95\n2,Bob,87'), 'text/csv'),
    'avatar': ('photo.jpg', io.BytesIO(b'\xff\xd8\xff\xe0'), 'image/jpeg')
}

# 额外的表单数据
data = {
    'user_id': '10086',
    'description': '月度报告上传'
}

response = requests.post('https://httpbin.org/post', files=files, data=data)
result = response.json()

print(f"上传文件字段: {list(result['files'].keys())}")
print(f"表单数据: {result['form']}")

输出结果:

代码示例

上传文件字段: ['avatar', 'document']
表单数据: {'user_id': '10086', 'description': '月度报告上传'}

五、大文件流式下载

下载大文件时必须设置stream=True,否则整个文件会先加载到内存中,可能导致内存溢出。使用iter_content()分块读取写入是推荐的做法。

代码示例

import requests

def download_file(url, save_path, chunk_size=8192):
    """流式下载文件"""
    response = requests.get(url, stream=True, timeout=30)
    total_size = int(response.headers.get('content-length', 0))
    downloaded = 0

    with open(save_path, 'wb') as f:
        for chunk in response.iter_content(chunk_size=chunk_size):
            if chunk:
                f.write(chunk)
                downloaded += len(chunk)
                if total_size > 0:
                    progress = (downloaded / total_size) * 100
                    print(f"\r下载进度: {progress:.1f}% ({downloaded}/{total_size})", end='')

    print(f"\n下载完成: {save_path}")
    return save_path

# 下载示例文件
url = 'https://httpbin.org/json'
save_path = 'downloaded_data.json'

# 模拟下载(实际保存的是JSON文本)
response = requests.get(url, stream=True)
with open(save_path, 'wb') as f:
    for chunk in response.iter_content(chunk_size=8192):
        f.write(chunk)

# 验证下载内容
with open(save_path, 'r', encoding='utf-8') as f:
    print(f"文件内容前100字符: {f.read(100)}")

输出结果:

代码示例

文件内容前100字符: {
  "slideshow": {
    "author": "Yours Truly",
    "date": "date of publication",
    "slides": [

六、应用场景

  • 用户头像上传:通过files参数将图片文件上传到服务器

  • 数据报表下载:通过流式下载获取大型CSV或Excel文件

  • 批量文件上传:同时上传多个文件和表单元数据


重要提示:上传文件时必须以二进制模式打开文件('rb'),不能使用文本模式。下载大文件时务必设置stream=True,否则整个文件会先加载到内存中。使用iter_content()时建议设置合理的chunk_size(通常8192或65536)。

七、上传下载方式对比

操作 方式 内存占用 适用场景
小文件上传 files参数 图片、文档等小文件
大文件上传 分块读取+上传 视频、大型数据文件
小文件下载 response.content JSON、小文档
大文件下载 stream+iter_content 极低 视频、压缩包等大文件

八、常见问题

为什么上传文件必须用'rb'模式?

文件上传使用的是multipart/form-data编码,需要传输原始字节数据。如果用文本模式('r'),Python会对数据进行编码转换(如换行符处理),可能导致文件内容损坏。

stream=True和stream=False有什么区别?

stream=False(默认)会将整个响应体加载到内存后再返回;stream=True会延迟下载响应体,允许使用iter_content()分块读取,适合下载大文件,避免内存溢出。

如何获取下载文件的原始文件名?

可以从响应头的Content-Disposition字段中提取:response.headers.get('Content-Disposition', ''),通常格式为attachment; filename="example.pdf"

chunk_size应该设置多大合适?

通常8192(8KB)是平衡内存和性能的合理选择。对于非常大的文件,可以设置为65536(64KB)以减少IO操作次数。过小会增加IO次数,过大会增加内存占用。

标签: requests 文件上传 文件下载 流式下载 files参数 Python网络

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: requests Cookie处理教程 - 发送接收会话管理详解 下一篇: requests SSL验证与重试机制指南 - 安全与可靠性实战

poll相关推荐