从JSON串中提取数据的实用指南
在数据交互日益频繁的今天,JSON(JavaScript Object Notation)已成为最常用的数据交换格式之一,无论是调用API接口、读取配置文件,还是处理前端与后端的数据传输,我们经常需要从JSON串中提取所需数据,本文将以通俗易懂的方式,结合不同场景和工具,详细介绍从JSON串中取数据的方法。
JSON基础:认识数据结构
在提取数据前,先要理解JSON的数据结构,JSON的核心是“键值对”(Key-Value Pair),通过键(Key)可以快速定位对应的值(Value),常见的JSON数据结构有两种:
对象(Object)
用 表示,由多个键值对组成,键是字符串,值可以是字符串、数字、布尔值、数组、对象或null。
{
"name": "张三",
"age": 25,
"isStudent": false,
"courses": ["数学", "英语"],
"address": {
"city": "北京",
"district": "海淀区"
}
}
数组(Array)
用 [] 表示,由多个有序值组成,值可以是任意JSON数据类型。
[
{"id": 1, "name": "商品A"},
{"id": 2, "name": "商品B"}
]
从JSON串中取数据的常用方法
JavaScript/TypeScript:原生操作与库函数
(1)原生方法:逐层“点”取或“方括号”取
对于简单的JSON对象,可以直接通过“点(.)”或“方括号([])”访问嵌套的值。注意:JSON本质是字符串,需先通过 JSON.parse() 转换为JavaScript对象。
// 假设从API获取的JSON字符串
const jsonStr = '{"name":"张三","age":25,"address":{"city":"北京"}}';
// 1. 转换为对象
const dataObj = JSON.parse(jsonStr);
// 2. 取一级数据:用点或方括号
console.log(dataObj.name); // 输出:张三
console.log(dataObj["age"]); // 输出:25
// 3. 取嵌套数据:逐层点取
console.log(dataObj.address.city); // 输出:北京
// 4. 处理数组:通过索引取
const jsonArrayStr = '[{"id":1},{"id":2}]';
const dataArray = JSON.parse(jsonArrayStr);
console.log(dataArray[0].id); // 输出:1
(2)安全访问:避免“未定义”报错
直接访问嵌套属性时,若中间层不存在(如 dataObj.address.country 会报错),可用可选链操作符(,ES2020+)或逻辑与(&&)避免报错:
// 可选链:若address不存在,直接返回undefined,不会报错 console.log(dataObj.address?.country); // 输出:undefined // 逻辑与:若前一级为假,则不执行后一级 console.log(dataObj.address && dataObj.address.country); // 输出:undefined
(3)动态取值:用变量作为键
当键是动态值时,需用方括号([])而非点():
const key = "name"; console.log(dataObj[key]); // 输出:张三(正确) // console.log(dataObj.key); // 错误:会查找dataObj的"key"属性,而非"name"
(4)使用库:Lodash简化操作
Lodash提供了更强大的取值工具,如 get() 方法支持默认值和深层访问:
const _ = require("lodash");
const data = { a: { b: { c: 1 } } };
// 安全取嵌套值,若路径不存在则返回默认值
console.log(_.get(data, "a.b.c", 0)); // 输出:1
console.log(_.get(data, "a.b.d", "默认")); // 输出:默认
Python:字典操作与第三方库
(1)原生方法:json.loads() + 字典访问
Python中需用 json.loads() 将JSON字符串转换为字典,再通过键或索引取值:
import json
json_str = '{"name":"张三","age":25,"courses":["数学","英语"]}'
data_dict = json.loads(json_str)
# 取一级数据
print(data_dict["name"]) # 输出:张三
print(data_dict.get("age")) # 输出:25(get方法更安全,键不存在时返回None)
# 取嵌套数据
address = {"city": "北京", "district": "海淀区"}
data_dict["address"] = address # 添加嵌套对象
print(data_dict["address"]["city"]) # 输出:北京
# 取数组元素
print(data_dict["courses"][0]) # 输出:数学
(2)安全访问:dict.get() + 异常处理
直接用 [] 访问不存在的键会报 KeyError,推荐用 dict.get() 或 try-except:
# get方法:键不存在时返回None(可指定默认值)
print(data_dict.get("phone", "未设置")) # 输出:未设置
# try-except:避免嵌套层级过深时报错
try:
print(data_dict["address"]["country"])
except KeyError:
print("嵌套键不存在") # 输出:嵌套键不存在
(3)第三方库:jsonpath——JSON的“XPath”
当JSON结构复杂时,可用 jsonpath 库通过类似XPath的语法提取数据(需安装:pip install jsonpath):
from jsonpath import jsonpath
json_data = {
"store": {
"book": [
{"category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century"},
{"category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour"}
],
"bicycle": {"color": "red", "price": 19.95}
}
}
# 提取所有书的标题s = jsonpath(json_data, "$.store.book[*].title")
print(titles) # 输出:['Sayings of the Century', 'Sword of Honour']
# 提取价格大于15的商品
expensive_items = jsonpath(json_data, "$..store[?(@.price > 15)]")
print(expensive_items) # 输出:[{'color': 'red', 'price': 19.95}]
Java:使用Gson或Jackson库
Java中需先将JSON字符串转换为对象或Map,再通过getter方法或键取值,推荐使用Gson或Jackson库。
(1)Gson:转换为自定义对象或Map
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.util.Map;
public class JsonDemo {
public static void main(String[] args) {
String jsonStr = "{\"name\":\"张三\",\"age\":25,\"address\":{\"city\":\"北京\"}}";
// 1. 转换为JsonObject(类似Map)
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(jsonStr, JsonObject.class);
// 取一级数据
String name = jsonObject.get("name").getAsString();
System.out.println(name); // 输出:张三
// 取嵌套数据
JsonObject address = jsonObject.getAsJsonObject("address");
String city = address.get("city").getAsString();
System.out.println(city); // 输出:北京
// 2. 转换为Map(适用于动态键)
Map<String, Object> dataMap = gson.fromJson(jsonStr, Map.class);
System.out.println(dataMap.get("age")); // 输出:25
}
}
(2)Jackson:使用ObjectMapper
Jackson是Java生态中更常用的JSON库,功能更丰富:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonDemo {
public static void main(String[] args) throws Exception {
String jsonStr = "{\"name\":\"张三\",\"courses\":[\"数学\",\"英语\"]}";
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(jsonStr);
// 取一级数据
String name = rootNode.get("name").asText();
System.out.println(name); // 输出:张三
// 取数组数据
JsonNode coursesNode = rootNode.get("courses");
for (int i = 0; i < coursesNode.size(); i++) {
System.out.println(coursesNode.get(i).asText()); // 输出:数学、英语
}
}
}


还没有评论,来说两句吧...