Python requests库Response.read/.text调用报错问题排查
报错原因说明
- 第一个
AttributeError: 'Response' object has no attribute 'read'报错:read()是Python标准库urllib请求返回的类文件对象的读取方法,requests库返回的Response响应对象没有提供这个方法,属于不同库的API记忆混淆导致的调用错误。 - 第二个
TypeError: a bytes-like object is required, not 'str'报错:打开本地zip文件时使用了wb即二进制写入模式,该模式要求写入内容必须是字节(bytes)类型;但response.text是requests自动根据响应头编码将内容解码生成的字符串(str)类型,类型不匹配触发报错。就算把文件打开模式改成文本模式强行写入,zip属于二进制压缩文件,编码转义过程会破坏文件结构,最终得到的压缩包也无法正常解压。
正确修改方式
requests的Response对象提供了content属性,会直接返回响应的原始二进制字节数据,完全匹配二进制文件写入的要求,替换对应读取逻辑即可正常下载。
修复后的完整可运行代码:
import requests feeds = [str(i) for i in range(2002, 2023)] for feed in feeds: link = f"https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-{feed}.json.zip" # 增加timeout参数避免请求无限挂起 response = requests.get(link, timeout=30) if response.status_code == 200: print(f"成功下载{feed}年CVE数据") with open(f"{feed}.zip", "wb") as f: f.write(response.content)
补充优化:如果后续下载单文件体积较大的资源,担心一次性把整个文件加载到内存占用过高,可以给
requests.get()传入stream=True参数,分块迭代写入文件,示例写法:response = requests.get(link, stream=True, timeout=30) if response.status_code == 200: with open(f"{feed}.zip", "wb") as f: # 每次写入1KB大小的块 for chunk in response.iter_content(chunk_size=1024): if chunk: f.write(chunk)
内容的提问来源于stack exchange,提问作者PawnShopChessboard
相关产品推荐
相关产品推荐

