接口测试 命名行下 JSON 处理工具:jq

胡刚 · 2016年02月06日 · 最后由 JennyHui 回复于 2016年03月04日 · 2548 次阅读
本帖已被设为精华帖!

1.背景

接口返回的数据类型是 JSON,在命令行下通过 curl 获取到接口返回的数据,往往是一大堆数据,怎样在一大堆数据中获取到我想要的数据,就需要一个特定的工具:jq,格式化输出,方便校验。

2.jq 是什么

jq 是轻量级和便捷的命令行 JSON 解析器。

jq is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text.

3.install

linux && OS X

git clone https://github.com/stedolan/jq.git
cd jq
autoreconf -i
./configure --disable-maintainer-mode
make
sudo make install

4.常用方法

格式化:.
hugangdeMacBook-Pro:~ root# curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.'
{
  "error": 0,
  "status": "success",
  "date": "2016-02-02",
  "results": [
    {
      "currentCity": "shanghai",
      "pm25": "170",
      "index": [
        {
          "title": "穿衣",
          "zs": "较冷",
          "tipt": "穿衣指数",
          "des": "建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。"
        },
        {
          "title": "洗车",
          "zs": "较适宜",
          "tipt": "洗车指数",
          "des": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"
        },
        {
          "title": "旅游",
          "zs": "适宜",
          "tipt": "旅游指数",
          "des": "天气较好,气温稍低,会感觉稍微有点凉,不过也是个好天气哦。适宜旅游,可不要错过机会呦!"
        },
        {
          "title": "感冒",
          "zs": "易发",
          "tipt": "感冒指数",
          "des": "昼夜温差很大,易发生感冒,请注意适当增减衣服,加强自我防护避免感冒。"
        },
        {
          "title": "运动",
          "zs": "较适宜",
          "tipt": "运动指数",
          "des": "天气较好,无雨水困扰,较适宜进行各种运动,但因气温较低,在户外运动请注意增减衣物。"
        },
        {
          "title": "紫外线强度",
          "zs": "弱",
          "tipt": "紫外线强度指数",
          "des": "紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"
        }
      ],
      "weather_data": [
        {
          "date": "周二 02月02日 (实时:3℃)",
          "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/qing.png",
          "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/qing.png",
          "weather": "晴",
          "wind": "微风",
          "temperature": "5 ~ 0℃"
        },
        {
          "date": "周三",
          "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/qing.png",
          "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
          "weather": "晴转多云",
          "wind": "微风",
          "temperature": "7 ~ 2℃"
        },
        {
          "date": "周四",
          "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/xiaoyu.png",
          "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/yin.png",
          "weather": "小雨转阴",
          "wind": "东风微风",
          "temperature": "6 ~ 2℃"
        },
        {
          "date": "周五",
          "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
          "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/qing.png",
          "weather": "多云转晴",
          "wind": "北风微风",
          "temperature": "9 ~ 1℃"
        }
      ]
    }
  ]
}


获取特定字段:.特定字段

获取 status 字段

curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.status'
"success"
数组操作

获取数组中第一个元素的 currentCity 字段

hugangdeMacBook-Pro:~ hugang$ curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.results[0].currentCity'
"shanghai"
重新组合

.results[]:返回 results 数组所有数据; |:the output of one filter into the input of another,类似管道符;{biaoti: .title, miaoshu: .des} 将 input 中.title,.des 做为 biaoti,miaoshu 的 value。

hugangdeMacBook-Pro:~ hugang$ curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.results[] | .index[] | {biaoti: .title, miaoshu: .des}'
{
  "biaoti": "穿衣",
  "miaoshu": "建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。"
}
{
  "biaoti": "洗车",
  "miaoshu": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"
}
{
  "biaoti": "旅游",
  "miaoshu": "天气较好,气温稍低,会感觉稍微有点凉,不过也是个好天气哦。适宜旅游,可不要错过机会呦!"
}
{
  "biaoti": "感冒",
  "miaoshu": "昼夜温差很大,易发生感冒,请注意适当增减衣服,加强自我防护避免感冒。"
}
{
  "biaoti": "运动",
  "miaoshu": "天气较好,无雨水困扰,较适宜进行各种运动,但因气温较低,在户外运动请注意增减衣物。"
}
{
  "biaoti": "紫外线强度",
  "miaoshu": "紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"
}
获取多个结果

,分隔多个结果

curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.error, .date'
0
"2016-02-02"
长度

length 根据 input 判断长度,字符串,数组,对象的长度

JSON 对象:

hugangdeMacBook-Pro:~ hugang$ curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.| length'
4

JSON 数组

curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.results[] | .index | length'
6

字符串

curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '.status | length'
7

keys
curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq '. | keys' 
[
  "date",
  "error",
  "results",
  "status"
]
-S 根据 key 排序输出
curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq -S 'keys'
[
  "date",
  "error",
  "results",
  "status"
]
map(foo)

invoke filter foo for each input

echo '[1,5,3,0,7]' | jq 'map(.+11)'
[
  12,
  16,
  14,
  11,
  18
]
select(foo)

返回满足条件的数据

echo '[1,5,3,0,7]' | jq 'map(select(.<2))'
[
  1,
  0
]
if-then-else-end

条件判断

curl 'http://api.map.baidu.com/telematics/v3/weather?location=shanghai&output=json&ak=W69oaDTCfuGwzNwmtVvgWfGH' -s | jq 'if .error==0 then "ok" elif .==1 then "false" else "null" end'
"ok"

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 9 条回复 时间 点赞

不错,自己正在安装使用,谢谢楼主的分享

多谢楼主分享。mac 下面可以 brew install jq 一键安装,适合我这种懒人。

很赞!学习了

楼主,https 的怎么搞

—— 来自 TesterHome 官方 安卓客户端

#5 楼 @zhuda 不管你的接口是 http or https,只要返回的是 json 格式,都可以用 jq 格式化;

用截包工具貌似也行吧?

#7 楼 @tianying 当然有很多工具可以展示 json;请注意标题,作用域是在命令行下

谢谢楼主 分享 学习了~不过应该还没有机会再项目中使用这个~

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册