You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go语言中解析多个独立的JSON对象?

如何在Go中解析多个独立的JSON对象

我完全懂你碰到的这个坑——用字符串替换把}{改成},{再套数组的方法看起来简单,但只要某个JSON的字符串字段里刚好出现}{(比如描述里包含类似代码片段的内容),整个解析就直接崩了,根本不靠谱。

针对你处理Common Crawl数据的场景,其实有两种更稳妥的解决方案,分情况来看:


情况1:数据是每行一个JSON对象(Common Crawl的标准输出格式)

Common Crawl的索引返回结果本来就是JSON Lines格式(每行一个完整的JSON对象),这种情况下直接用bufio.Scanner逐行读取解析就好,既高效又不会出错:

package main

import (
    "bufio"
    "encoding/json"
    "fmt"
    "strings"
)

// 根据Common Crawl的输出结构定义结构体,按需添加字段
type CrawlEntry struct {
    URL       string `json:"url"`
    Status    string `json:"status"`
    Timestamp string `json:"timestamp"`
}

func main() {
    // 假设resp_body是你获取到的响应体字节数组
    respBody := `{"url":"https://www.netflix.com","status":"200","timestamp":"20180426123456"}
{"url":"https://help.netflix.com","status":"200","timestamp":"20180426123501"}`

    scanner := bufio.NewScanner(strings.NewReader(respBody))
    for scanner.Scan() {
        line := scanner.Bytes()
        var entry CrawlEntry
        if err := json.Unmarshal(line, &entry); err != nil {
            fmt.Printf("解析单行JSON失败: %v\n", err)
            continue
        }
        // 这里处理解析后的对象
        fmt.Printf("抓取URL: %s | 状态码: %s\n", entry.URL, entry.Status)
    }

    if err := scanner.Err(); err != nil {
        fmt.Printf("读取数据出错: %v\n", err)
    }
}

这种方法完全不需要修改原始数据,完美适配Common Crawl的输出规范,而且内存占用也更低——不需要把整个响应体加载到内存里,逐行处理就行。


情况2:数据是无换行的连续JSON对象

如果碰到的是完全连续的JSON(比如{"something":"foo"}{"something-else":"bar"}这种没有换行的情况),可以用json.Decoder的循环解析能力,它会自动跳过JSON之间的空白字符,并且能判断是否还有后续对象:

package main

import (
    "encoding/json"
    "fmt"
    "strings"
)

type Item struct {
    Something     string `json:"something"`
    SomethingElse string `json:"something-else"`
}

func main() {
    rawData := `{"something":"foo"}{"something-else":"bar"}`
    decoder := json.NewDecoder(strings.NewReader(rawData))

    for {
        var item Item
        err := decoder.Decode(&item)
        if err != nil {
            // 要么解析完所有对象,要么出错,直接退出循环
            break
        }

        // 处理解析后的对象
        if item.Something != "" {
            fmt.Printf("Something: %s\n", item.Something)
        }
        if item.SomethingElse != "" {
            fmt.Printf("Something Else: %s\n", item.SomethingElse)
        }

        // 检查是否还有未解析的JSON对象
        if !decoder.More() {
            break
        }
    }
}

这个方法彻底避免了字符串替换的风险,不管JSON里有没有嵌套的}{,json.Decoder都能正确识别每个独立的JSON边界。


总结一下:针对你的Common Crawl场景,优先用第一种逐行解析的方案,这是最贴合数据源的做法。如果碰到其他连续JSON的场景,就用第二种json.Decoder循环解析的方式。

内容的提问来源于stack exchange,提问作者Ice3man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:00:18