oss2 不支持直接上传 url,需先用 requests.get(url, stream=true) 获取响应流,再通过 bucket.put_object(data=resp.raw, headers={'content-type': ...}) 流式上传,避免内存溢出并确保 content-type 正确。

oss2 本身不支持直接上传网络 URL,必须先下载到内存或临时文件,再调用上传接口——这是绝大多数人卡住的第一步。
为什么不能直接传 URL 给 bucket.put_object?
put_object 接收的是 bytes、file-like object 或 str(文本),不是 HTTP 链接。你传一个字符串 URL 过去,OSS 会把它当纯文本存进去,而不是下载并上传内容。
- 常见错误现象:
result.status返回 200,但 OSS 控制台里打开文件是明文 URL 字符串,不是图片 - 根本原因:没做
requests.get(url).content这一步解包 - 风险点:大图/视频直接
.content加载进内存可能 OOM,尤其并发爬取时
怎么安全地把 requests.Response 流式写入 OSS?
用 put_object 传 response.raw 是最省内存的方式,但必须确保 response 保持连接未关闭,且 headers 正确(比如 Content-Type)。
- 必须加
stream=True:否则response.raw不可用 - 必须手动设置
Content-Type:OSS 不会自动识别,否则 CDN 或浏览器可能无法正确渲染 - 示例写法:
resp = requests.get(url, stream=True)
bucket.put_object(
key=f'img/{uuid.uuid4()}.jpg',
data=resp.raw,
headers={'Content-Type': resp.headers.get('content-type', 'image/jpeg')}
)
注意:resp.raw 是 socket 层的原始流,OSS SDK 会边读边上传,不缓存全量到内存。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
put_object_from_file 和 put_object 选哪个?
如果已保存为本地文件,优先用 put_object_from_file;如果只在内存里(比如 BytesIO),必须用 put_object。
-
put_object_from_file自动处理文件打开、分块读取、关闭,还支持断点续传(需开启oss2.ResumableUpload) -
put_object更灵活,但你要自己保证数据对象生命周期——比如BytesIO不能提前 close,否则上传中途报ValueError: I/O operation on closed file - 大文件(>100MB)建议走分片上传:
oss2.ResumableUpload,避免单次请求超时或中断后重传全部
AccessKey 硬编码在代码里会出大事
哪怕只是测试脚本,也别把 access_key_id 和 access_key_secret 写死。一旦误提交到 GitHub,密钥就彻底泄露。
- 最低要求:用环境变量,
os.getenv('OSS_ACCESS_KEY_ID') - 更稳妥:配合
configparser+.gitignore排除 config.ini - 生产环境必须用 RAM 子账号,且只授予最小权限(比如仅
AliyunOSSFullAccess中的PutObject和ListBucket) - OSS Endpoint 别写错:
https://oss-cn-hangzhou.aliyuncs.com是标准域名,不是 bucket 域名(https://your-bucket.oss-cn-hangzhou.aliyuncs.com)
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










