话说回来,你有没有碰到过那种场景?从网上爬点数据吧,或者调某个API接口,结果“duang”一下甩给你一大坨密密麻麻的文字,看着像某种神秘代码,但仔细瞧瞧,又有点规律,有花括号{}
,有方括号[]
,键值对还用冒号:
隔开。对,那玩意儿多半就是JSON了(JavaScript Object Notation),现在简直是互联网世界里数据交换的“通用语”。它简洁、轻量,人看起来也算勉强能懂,可让咱的Python程序直接去读这堆原始字符串?那不得疯掉!就像你抓了一把生米,得煮熟了才能吃不是?所以,python怎么解析json,把这“生米”煮成Python能用的“熟饭”,就成了我们绕不开的话题,而且说实话,掌握了这个,你很多数据处理、网络交互的事儿都能迎刃而解,一下子感觉就通透了许多。
别想得太复杂,Python这方面做得简直是保姆级的友好。标准库里就自带了一个超级好用的模块,名字就叫json
。对,就是这么直白,见到JSON就找它,准没错!它就是来干这事的,把JSON格式的数据和Python里的数据结构之间做个漂亮的转换。
那具体怎么转呢?无非就是两种最常见的姿势:一种是你手里已经有了一段JSON格式的字符串,可能是从网页内容里抠出来的,也可能是API接口直接返回的文本。另一种呢,是你的JSON数据安安静静地躺在电脑里的一个文件里,扩展名通常是.json
。针对这两种情况,json
模块给咱们准备了两把“瑞士军刀”:json.loads()
和 json.load()
。
先说json.loads()
,注意最后的那个’s’,我总把它记成“string”,因为它就是用来处理JSON字符串的。想象一下,你写了个小程序去抓取某个网站的数据,返回的内容里有一段长得像这样的:
json
{
"name": "李华",
"age": 25,
"isStudent": true,
"major": "Computer Science",
"courses": ["Python编程", "数据结构", "算法分析"],
"address": {
"city": "北京",
"zip": "100000"
},
"isNullValue": null
}
这段东西,在Python里,最开始它可能就是个普普通通的字符串变量,比如叫 json_string_data
。你直接打印 json_string_data
,看到的就是上面那堆字符。可你想要的是李华的年龄(25),想知道他是不是学生(true),想拿到他的课程列表!这时候,json.loads()
就闪亮登场了。
你只需要这样简单粗暴地一搞:
“`python
import json
json_string_data = ”’
{
“name”: “李华”,
“age”: 25,
“isStudent”: true,
“major”: “Computer Science”,
“courses”: [“Python编程”, “数据结构”, “算法分析”],
“address”: {
“city”: “北京”,
“zip”: “100000”
},
“isNullValue”: null
}
”’ # 真实场景下,这串通常是动态获取的
try:
python_data = json.loads(json_string_data)
# 打印看看,是不是变了?
print(type(python_data)) # 瞧瞧,变成 <class 'dict'> 啦!
print(python_data)
# 现在,你可以像操作Python自己的字典和列表一样,为所欲为啦!
print("姓名:", python_data['name'])
print("年龄:", python_data['age'])
print("是学生吗:", python_data['isStudent'])
print("第一门课程:", python_data['courses'][0])
print("所在城市:", python_data['address']['city'])
print("这个null值对应的是:", python_data['isNullValue']) # 在Python里,null就成了None
except json.JSONDecodeError as e:
print(f”天呐,这JSON格式不对啊!解析失败了: {e}”)
# 实际应用中,你得好好处理这个错误,可能是数据源有问题
except KeyError as e:
print(f”想取的数据找不到啊!这个键不存在: {e}”)
# 比如你尝试访问一个根本不存在的键 ‘school’
“`
看到没?经过json.loads()
这么一“消化”,那堆看似杂乱的JSON字符串,瞬间就变成了Python里我们最熟悉不过的数据结构——字典(对应JSON的object {}
)和列表(对应JSON的array []
)。JSON里面的字符串就变成了Python的str,数字变成了int或float,布尔值(true/false)变成了Python的布尔值(True/False),而JSON那个特殊的null
,在Python里就变成了None
。这对应关系,简直太直观了!
一旦转换成了字典和列表,接下来的事儿就简单了。你想取哪个值,就像平时操作字典一样,用键来访问(比如 python_data['name']
);想拿到列表里的元素,就像操作列表一样,用索引来取(比如 python_data['courses'][0]
)。如果数据是嵌套的,就像上面例子里的address
,它本身是个JSON对象(解析后就是个字典),你就可以链式地访问:python_data['address']['city']
。一层一层“剥洋葱”,直到拿到你想要的最里层的数据。这过程,是不是比直接在字符串里用各种切片、查找来抠数据方便多了?简直是天壤之别!
再来说说json.load()
,注意,这次结尾没’s’了,它通常用来处理JSON文件。想象你有了一个叫 config.json
的配置文件,里面存着你程序的一些设置,格式就是JSON:
json
// config.json 文件内容
{
"database": {
"host": "localhost",
"port": 5432,
"username": "admin",
"password": "secret_password"
},
"timeout": 30,
"enabled_features": ["feature_a", "feature_b"]
}
你想在程序启动时读取这些配置。这时候,你当然可以先把整个文件读成一个大字符串,然后再用json.loads()
去解析。但这有点绕,也不够高效。json.load()
就是为这种情况而生的,它可以直接接收一个文件对象作为参数,然后帮你把整个文件的JSON内容一次性解析出来。
用法通常是这样:
“`python
import json
try:
# 打开文件,记住要指定编码,特别是文件里有中文的时候,utf-8是王道
with open(‘config.json’, ‘r’, encoding=’utf-8′) as f:
# 直接把文件对象f传给json.load()
config_data = json.load(f)
# 现在 config_data 就是一个Python字典了,包含了文件里的所有配置
print("数据库主机:", config_data['database']['host'])
print("连接超时时间:", config_data['timeout'])
print("启用的第一个特性:", config_data['enabled_features'][0])
except FileNotFoundError:
print(“哎呀,配置文件 config.json 找不着啊!”)
except json.JSONDecodeError as e:
print(f”配置文件 config.json 格式不对!解析失败了: {e}”)
except KeyError as e:
print(f”配置文件里缺少关键信息: {e}”)
“`
看,是不是也很方便?json.load()
和json.loads()
其实干的是同一件事,就是解析JSON数据,只不过输入源不一样:一个是字符串,一个是文件对象。理解这一点,基本就掌握了Python解析JSON的核心。
当然,解析过程中难免会遇到“坑”。最常见的就是JSON格式本身有问题,比如少了个逗号,多了个冒号,或者引号没闭合。这时候,json.loads()
或json.load()
就会抛出json.JSONDecodeError
异常。所以,在实际代码里,用try...except
块把解析的代码包起来,是防止程序崩溃的必备操作,你得告诉程序,万一解析失败了该怎么办,是报错退出,还是给个默认值,或者记录个日志。
还有一种常见情况是,JSON数据是合法的,但里面可能不包含你期望的某个键。比如你解析了一个用户数据,你以为肯定会有个’email’字段,结果有些用户的数据里就没有。这时候你如果直接用 user_data['email']
去访问,Python就会给你一个KeyError
。为了避免这种尴尬,访问字典的时候,更“温柔”的方式是用它的 .get()
方法:user_data.get('email', 'N/A')
。这样写,如果’email’键存在,就返回对应的值;如果不存在,也不会报错,而是返回你指定的默认值(这里是’N/A’)。这个小技巧在处理来自不可控源(比如网络API)的数据时,非常非常实用。
总的来说,python怎么解析json?核心就在于灵活运用json
模块的json.loads()
和json.load()
这两兄弟,它们能把JSON格式的数据巧妙地转化成Python世界里游刃有余的字典和列表。然后,你就可以像操作Python原生数据结构一样,轻松地提取、修改、处理这些数据了。别忘了处理可能出现的格式错误(json.JSONDecodeError
)和键不存在(KeyError
,用.get()
更好)的情况,让你的程序更加健壮。一旦你掌握了这门手艺,面对各种爬虫数据、API响应、配置文件,都能底气十足地说一句:“小样儿,藏得挺深,看我把你解析出来!” 动手试试吧,敲几行代码,亲自感受一下Python解析JSON的丝滑流畅,你会发现,原来处理这些数据可以这么简单、这么高效。