解析HTTP响应中的复杂JSON数据
本文介绍了如何解析包含复杂 JSON 数据的 HTTP 响应。该 JSON 数据具有多层嵌套结构,包括列表和映射。为了从该 JSON 数据中提取特定信息,可以使用自定义函数 `findNested` 来递归地遍历映射并查找指定的键。`findNested` 函数会返回一个布尔值,指示该键是否找到,以及找到的值。利用此函数,可以轻松地提取所需字段,例如每个站点的 site_id、ip 和域名。
我正在针对 api 执行 http.postform,结果是 json。 json结构是这样的:
{
"sites": [
{
"site_id": 456,
"status": "pending-dns-changes",
"domain": "blabla",
"account_id": 123,
"acceleration_level": "advanced",
"site_creation_date": 1515455285000,
"ips": [
"1.2.3.4"
],
"dns": [
{
"dns_record_name": "something.bla.com",
"set_type_to": "cname",
"set_data_to": [
"something.x.incapdns.net"
]
}
],
"original_dns": [
{
"dns_record_name": "blabla2.com",
"set_type_to": "a",
"set_data_to": [
""
]
},
{
"dns_record_name": "blabla3.something.com",
"set_type_to": "a",
"set_data_to": [
"1.2.4.5"
]
},
],
"warnings": [],
"active": "bypass",
"support_all_tls_versions": false,
"use_wildcard_san_instead_of_full_domain_san": true,
"add_naked_domain_san": true,
"additionalerrors": [],
"display_name": "something.blablabla2.com",
"security": {
"waf": {
"rules": [
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.sql_injection",
"name": "sql injection"
},
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.cross_site_scripting",
"name": "cross site scripting"
},
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.illegal_resource_access",
"name": "illegal resource access"
},
{
"block_bad_bots": true,
"challenge_suspected_bots": false,
"id": "api.threats.bot_access_control",
"name": "bot access control"
},
{
"activation_mode": "api.threats.ddos.activation_mode.auto",
"activation_mode_text": "auto",
"ddos_traffic_threshold": 1000,
"id": "api.threats.ddos",
"name": "ddos"
},
{
"action": "api.threats.action.quarantine_url",
"action_text": "auto-quarantine",
"exceptions": [
{
"values": [
{
"urls": [
{
"value": "/neverbogus.pvr",
"pattern": "equals"
}
],
"id": "api.rule_exception_type.url",
"name": "url"
}
],
"id": 1618746719
},
{
"values": [
{
"urls": [
{
"value": "/doubleneverbogus.pvr",
"pattern": "equals"
},
{
"value": "/ddoubleneverbogus.pvr",
"pattern": "equals"
}
],
"id": "api.rule_exception_type.url",
"name": "url"
}
],
"id": 856301271
},
{
"values": [
{
"client_apps": [
"537"
],
"id": "api.rule_exception_type.client_app_id",
"name": "client app id"
}
],
"id": 58318563
},
{
"values": [
{
"ips": [
"192.168.66.66"
],
"id": "api.rule_exception_type.client_ip",
"name": "ip"
}
],
"id": 707083378
},
{
"values": [
{
"geo": {
"countries": [
"bf"
]
},
"id": "api.rule_exception_type.country",
"name": "country"
}
],
"id": 1432086237
},
{
"values": [
{
"user_agents": [
"gasdfafafdfasdfadsfadsffads"
],
"id": "api.rule_exception_type.user_agent",
"name": "user agent"
}
],
"id": 1876871261
},
{
"values": [
{
"parameters": [
"bogusparamnamehere234"
],
"id": "api.rule_exception_type.http_parameter",
"name": "http parameter"
}
],
"id": 1338747790
}
],
"id": "api.threats.backdoor",
"name": "backdoor protect"
},
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.remote_file_inclusion",
"name": "remote file inclusion"
},
{
"action": "api.threats.action.disabled",
"action_text": "ignore",
"id": "api.threats.customrule",
"name": "incaprules"
}
]
}
},
"seallocation": {
"id": "api.seal_location.none",
"name": "no seal "
},
"ssl": {
"origin_server": {
"detected": true,
"detectionstatus": "ok"
},
"custom_certificate": {
"active": false
},
"generated_certificate": {
"ca": "gs",
"validation_method": "dns",
"validation_data": [
{
"dns_record_name": "blablablasomething2",
"set_type_to": "txt",
"set_data_to": [
"somethingtexty"
]
}
],
"san": [
"*.blabla2.com"
],
"validation_status": "done"
}
},
"sitedualfactorsettings": {
"enabled": false,
"customareas": [],
"customareasexceptions": [],
"allowallusers": true,
"shouldsuggestapplicatons": true,
"allowedmedia": [
"ga",
"sms"
],
"shouldsendloginnotifications": true,
"version": 0
},
"login_protect": {
"enabled": false,
"specific_users_list": [],
"send_lp_notifications": true,
"allow_all_users": true,
"authentication_methods": [
"ga",
"sms"
],
"urls": [],
"url_patterns": []
},
"performance_configuration": {
"advanced_caching_rules": {
"never_cache_resources": [],
"always_cache_resources": []
},
"acceleration_level": "advanced",
"async_validation": true,
"minify_javascript": true,
"minify_css": true,
"minify_static_html": true,
"compress_jpeg": true,
"compress_jepg": true,
"progressive_image_rendering": false,
"aggressive_compression": false,
"compress_png": true,
"on_the_fly_compression": true,
"tcp_pre_pooling": true,
"comply_no_cache": false,
"comply_vary": false,
"use_shortest_caching": false,
"perfer_last_modified": false,
"prefer_last_modified": false,
"disable_client_side_caching": false,
"cache300x": false,
"cache_headers": []
},
"extended_ddos": 1000000,
"log_level": "security",
"incap_rules": [
{
"id": 51589,
"name": "wordpress",
"action": "api.rule_action_type.rule_action_alert",
"rule": "(url contains \"/xmlrpc.php$\" | url contains \"/wp-login.php$\") & (user-agent == \"mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/51.0.2704.103 safari/537.36\" | user-agent == \"mozilla/5.0 (windows nt 6.1; wow64; rv:40.0) gecko/20100101 firefox/40.1\")",
"creation_date": 1518810206000
},
{
"id": 52179,
"name": "no browser",
"action": "api.rule_action_type.rule_action_alert",
"rule": "(clienttype != browser & clienttype != spambot & clienttype != ddosbot & clienttype != sitehelper) & (user-agent != \"mozilla/5.0 (windows nt 6.1; wow64) applewebkit/534+ (khtml, like gecko) bingpreview/1.0b\" & user-agent != \"pingdom.com_bot_version_1.4_(http://www.pingdom.com/)\")",
"creation_date": 1519432068000
}
],
"res": 0,
"res_message": "ok",
"debug_info": {
"id-info": "13019"
}
},
api 文档:https://docs.imperva.com/bundle/cloud-application-security/page/api/sites-api.htm#list
对于我来说,理解 go 似乎非常痛苦,因为我才刚刚开始。 从我读到的内容来看,我应该用我期望的格式定义一个 struct 类型的对象。 有什么办法可以让我更轻松地解决这个问题吗?我有兴趣为每个单独的站点提取一些项目,例如 site_id / ips / 域。
不确定我应该如何解决这个问题。我一直在尝试了解 https://github.com/buger/jsonparser 但我无法真正理解如何使用它。
到目前为止我一直在做的是:
func main() {
fmt.Println("Starting this..")
formData := url.Values{
"api_id": {keyid},
"api_key": {apikey},
"page_size": {"100"},
"page_num": {"0"},
}
response, err := http.PostForm("https://my.imperva.com/api/prov/v1/sites/list", formData)
if nil != err {
fmt.Println("Ooops..", err)
}
log.Println(response.Status)
bodyBytes, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var results map[string]interface{}
fmt.Println(string(bodyBytes))
json.Unmarshal([]byte(bodyBytes), &results)
defer response.Body.Close()
}解决方案
如果您只需要提取几个字段,则实际上不需要定义复杂的 struct 类型来描述整个结构。您可以使用 stdlib 将 json 解组到 map[string]interface{},然后使用类似此函数的功能来查找有趣的键:
// findNested looks for a key named s in map m. If values in m map to other
// maps, findNested looks into them recursively. Returns true if found, and
// the value found.
func findNested(m map[string]interface{}, s string) (bool, interface{}) {
// Try to find key s at this level
for k, v := range m {
if k == s {
return true, v
}
}
// Not found on this level, so try to find it nested
for _, v := range m {
nm, ok := v.(map[string]interface{})
if ok {
found, val := findNested(nm, s)
if found {
return found, val
}
}
}
// Not found recursively
return false, nil
}
此代码仅处理嵌套映射。您可以稍微调整它以透视切片等。
今天关于《解析HTTP响应中的复杂JSON数据》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
解决PHP中使用mysqli_warning::fetch_assoc()方法的问题
- 上一篇
- 解决PHP中使用mysqli_warning::fetch_assoc()方法的问题
- 下一篇
- 使用PHP编写网络爬虫监控系统
-
- Golang · Go问答 | 1年前 |
- 在读取缓冲通道中的内容之前退出
- 139浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 戈兰岛的全球 GOPRIVATE 设置
- 204浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 如何将结构作为参数传递给 xml-rpc
- 325浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 如何用golang获得小数点以下两位长度?
- 478浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 如何通过 client-go 和 golang 检索 Kubernetes 指标
- 486浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 将多个“参数”映射到单个可变参数的习惯用法
- 439浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 将 HTTP 响应正文写入文件后出现 EOF 错误
- 357浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 结构中映射的匿名列表的“复合文字中缺少类型”
- 352浏览 收藏
-
- Golang · Go问答 | 1年前 |
- NATS Jetstream 的性能
- 101浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 如何将复杂的字符串输入转换为mapstring?
- 440浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 相当于GoLang中Java将Object作为方法参数传递
- 212浏览 收藏
-
- Golang · Go问答 | 1年前 |
- 如何确保所有 goroutine 在没有 time.Sleep 的情况下终止?
- 143浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3188次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3401次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3432次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4538次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3810次使用
-
- GoLand调式动态执行代码
- 2023-01-13 502浏览
-
- 用Nginx反向代理部署go写的网站。
- 2023-01-17 502浏览
-
- Golang取得代码运行时间的问题
- 2023-02-24 501浏览
-
- 请问 go 代码如何实现在代码改动后不需要Ctrl+c,然后重新 go run *.go 文件?
- 2023-01-08 501浏览
-
- 如何从同一个 io.Reader 读取多次
- 2023-04-11 501浏览

