用Python从URL读取和解析JSON文件
在Python中从URL读取JSON可将远程响应立即转换为可用的数据。使用urllib.request获取响应,然后将其正文传递给json.loads以获取字典或列表。此模式适用于公共API、托管的配置文件以及独立于代码变化的数据集。
Python从URL读取JSON示例
输出:
输出将显示在这里...
输出:
Squad: Super Hero Squad
Members: 3
示例工作原理
urllib.request.urlopen(url)发送同步GET请求并返回HTTP响应;with块在结束后关闭连接。response.read()以原始字节形式返回正文。json.loads直接接受字节,因此不需要手动执行.decode("utf-8")步骤。- 解析将JSON对象转换为Python dict,可通过
data["squadName"]进行索引访问,通过len(data["members"])获取数量。
在此运行时中,urlopen是同步的,因此不需要await和asyncio,即使许多教程将网络调用包装在异步代码中。
json.load 与 json.loads 的区别
两个函数都将JSON反序列化为Python对象;区别在于它们读取的来源。
| 函数 | 输入 | 使用时机 |
|---|---|---|
json.loads(...) | str或bytes值 | 内容已在内存中,如response.read() |
json.load(...) | 文件或流对象 | 有打开的句柄,如open(path)或响应本身 |
此处json.loads(response.read())和json.load(response)产生相同的dict。常见错误是传入错误类型:将字符串传给json.load或将文件对象传给json.loads会引发AttributeError或TypeError。
在Run Details中查看JSON请求
程序完成后打开Run Details。它将脚本发出的网络请求与运行时为执行代码加载的包分开显示。
| Run Details信号 | 含义 |
|---|---|
| Requests显示对raw.githubusercontent.com的GET请求,状态为200 | JSON文件已通过网络成功获取 |
| 请求时间(ms) | 获取本身花费的时间,与解析分开计算 |
| 请求返回403/404、被阻止或失败 | URL不可访问或未启用CORS,代码从未收到数据 |
| Packages为空(“No runtime packages”) | json和urllib是标准库,未安装任何内容 |
Packages部分为空证明此方法无需安装依赖。导入beautifulsoup4或pandas的示例会在此列出加载的包,如网页抓取示例;使用标准库读取JSON则不会列出任何包。
在浏览器中从URL读取只有在端点发送CORS标头时才有效。上述文件是GitHub raw上支持CORS的文件;没有这些标头的跨域URL会在代码运行前被阻止,表现为请求失败而不是JSONDecodeError。
从URL读取JSON的常见错误
错误:两次读取响应流。
错误示例:
raw = response.read()
data = json.loads(response.read())
正确示例:
data = json.loads(response.read())
原因:urlopen返回只能消费一次的流;第二次调用read()返回空字节。
错误:对已解析的JSON数组调用.get()。
错误示例:
data = json.loads(response.read())
first = data.get("name")
正确示例:
data = json.loads(response.read())
first = data[0] if isinstance(data, list) else data["name"]
原因:顶层JSON数组解析为Python列表,列表没有.get方法;需要使用索引访问。
错误处理和缺失键
urlopen对4xx和5xx响应抛出HTTPError,但错误对象仍可读取,因此可以通过用try/except捕获来解析JSON错误正文:
from urllib.error import HTTPError
try:
with urllib.request.urlopen(url) as response:
data = json.loads(response.read())
except HTTPError as err:
data = json.loads(err.read())
对于可选字段,使用data.get("key")返回None而不是引发KeyError。标准库json模块可安全解析不可信的输入,因此读取JSON时永远不要使用eval()。
FAQ
如何在Python中读取JSON文件?
对于远程文件,使用urllib.request.urlopen(url)打开并将字节传递给json.loads。对于磁盘上的文件,使用with open(path) as f: data = json.load(f)。两者都返回Python dict或列表。
json.load和json.loads有什么区别?
json.load从文件或流对象读取,而json.loads从str或bytes值读取。末尾的”s”代表string(字符串)。当内容已在内存中时使用loads。
在Python中读取JSON需要requests库吗?
不需要。urllib.request和json都是标准库,因此无需任何安装即可获取和解析JSON。requests库添加了.json()辅助方法和会话管理等便利功能,但它是第三方依赖。
Python中的JSON是什么?
JSON是结构化数据的文本格式。Python将JSON对象映射为dict,将数组映射为列表,将基本类型映射为str、int、float、bool和None——这正是json.loads解析后返回的内容。