requests.get() 默认返回响应对象,图片等二进制资源须用 response.content(bytes)而非 response.text(会解码报错);保存时需 'wb' 模式、安全提取文件名、检查 status_code、加 headers 和超时重试。

requests.get() 默认不返回图片二进制流?
不是默认不返回,而是 response.text 会尝试解码成字符串(比如 UTF-8),对图片这种非文本内容直接用它会报错或存出乱码文件。必须用 response.content —— 它是原始的 bytes 对象,和图片文件磁盘里的字节完全一致。
常见错误现象:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0,就是误用了 .text。
- 所有图片、PDF、ZIP 等非文本资源,一律用
response.content - 加
stream=True参数不是必须的,但对大图能节省内存(避免一次性全载入) - 记得检查
response.status_code == 200,否则可能存的是 404 HTML 页面
保存时文件名怎么从 URL 提取才安全
直接用 url.split('/')[-1] 很危险:URL 可能带参数(?v=2&t=171...)、路径含中文、或根本没有文件后缀(如 https://example.com/photo/123)。存出来可能是 123?v=2 这种非法文件名,或缺后缀导致打不开。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
urllib.parse.urlparse()解析 URL,取.path再os.path.basename(),比split更稳 - 用
response.headers.get('content-type')补充后缀(如image/jpeg→.jpg),优先级高于 URL 里的后缀 - 文件名含非法字符(
\ / : * ? " |)必须过滤,Windows 和 macOS 都会报错
用 open() 保存二进制内容要注意什么
关键就一个模式:必须用 'wb'(write binary),不能用 'w' 或 'a'。Python 3 中文本模式会强制编码,而 bytes 无法 encode 成 str。
示例片段:
with open(filename, 'wb') as f:
f.write(response.content)其他要点:
- 路径不存在时会报
FileNotFoundError,提前用os.makedirs(os.path.dirname(filename), exist_ok=True) - 不要用
response.iter_content()小块写入——除非图片超大(>100MB)且内存紧张,否则没必要,反而易出错 - 如果图片来自防盗链站点,记得加
headers={'User-Agent': 'Mozilla/5.0...'},否则response.status_code可能是 403
requests 保存图片比 urllib 更简单,但别忽略重试和超时
requests 的 API 确实比 urllib.request 直观,但网络请求不稳定。一次 get() 失败就中断,实际爬虫中很常见。
必须加的防护:
-
timeout=(3, 7):分连接超时和读取超时,避免卡死 - 用
try/except requests.exceptions.RequestException捕获所有网络异常 - 简单重试(比如最多 3 次)比直接失败更实用,可用
time.sleep(1)避免被封 - 注意:有些网站返回 200 但内容是 placeholder 图(比如 base64 编码的灰色占位符),需额外校验
len(response.content) > 1024
真正麻烦的从来不是“怎么存”,而是“怎么确保每次拿到的是真图、没截断、没被反爬替换”。这些细节不处理,批量保存几百张图时总有几张打不开,还得回头查。


















