V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
faketemp
V2EX  ›  分享创造

Json 数据通用提取工具[离线]

  •  
  •   faketemp · 308 天前 · 2166 次点击
    这是一个创建于 308 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Golang 实现的一款通用型 JSON 数据提取工具,支持自动识别 JSON 数据节点并有序提取为 CSV 文件。
    Convenient JSON data extraction tool.

    使用简介

    > Json2Csv:请指定 JSON 格式文件路径(支持批量)...
    > Json2Csv [-k root.data.items] data.json data2.txt ...
    Usage of main.exe:
      -h    显示帮助
      -k string
            设置 Json 中数据所处路径,如'-k root.topics.data'
    

    支持以下常见 JSON 数据格式:

    数据位于根 /一级节点下

    [{"ID":0,"Name":"Lucy","Age":17,"Granted":true},{"ID":1,"Name":"Lily","Age":20,"Granted":false}]
    或者
    {"part":1,"items":[{"title":"one","price":23},{"title":"two","price":92},{"title":"three","price":5623}]}
    

    数据提取命令:Json2Csv test1.json test2.json

    拖放 json 文件到主程序或命令行均可运行,如 JSON 数据位于根 /一级节点下程序可自动检测并提取

    数据位于任意多级节点下

    {"data":{"items":[{"title":"one","price":23},{"title":"two","price":92},{"title":"three","price":5623}]}}
    

    数据位于"data.items"多级节点下,-k 参数简单指定数据路径即可,如
    数据提取命令:Json2Csv -k data.items test.json
    测试文件:-k 参数 JSON 示例

    说明

    • 为什么不用在线服务?
      内网数据隐私不能公开; JSON 文件较大(比如超过 20M)大多数在线服务都无法支持。
    • 为什么不用 Pandas 等?
      内网 python 和常用库的安装维护等都很麻烦; Python 工具只能自己用(分享不便);每个 json 都要分析后对应编写测试代码通用性欠佳; Pandas 默认会导致长数据输出科学计数法很麻烦...
    • 为什么不用 utools/jq 等工具?
      这些工具提取 json 中个别字段的文本很方便,但想将所有数据批量输出却很麻烦;而且使用门槛较高 jq 兼容性较差,比如 json 文件识别报错、不支持 win7 系统等等

    Github 链接

    第 1 条附言  ·  306 天前

    兼容处理数据区域非数组结构而是一个对象的情况,如 Json2Csv -k data.items test.json

    {"part":1,"data":{"items":{"1":{"title":"one","name":"test1"},"2":{"title":"two","name":"test2"},{"3":{"title":"three","name":"test3"}}}}
    
    17 条回复    2023-07-07 20:53:02 +08:00
    512357301
        1
    512357301  
       308 天前 via Android
    有时间试试。
    不知道楼主有没有研究过 https://data.page ,他们家的 json 转 csv/excel 贼好用,它是全量转,不能限制 json 结构,不过全量转就行了,性能也可以接受,唯一的不好就是它是在线的
    xiangyuecn
        2
    xiangyuecn  
       308 天前
    用 html 做一个也简单,100M 的 JSON.parse 无压力,单个 html 只需拖进浏览器就能访问[离线]

    天然自带 UI😂 拖拽 json 文件、手动选择 json 文件都 ok

    0 依赖
    faketemp
        3
    faketemp  
    OP
       308 天前 via iPhone
    @xiangyuecn 求分享
    pagxir
        4
    pagxir  
       308 天前
    为啥不用 jq 呢,不好用?
    faketemp
        5
    faketemp  
    OP
       308 天前
    @pagxir 内网机系统必须 win7/xp ,jq/dsq/fx 等工具基本都跑不起来,而且实测几个常用几十 M 的 json 这些工具大多报错解析失败,起码在我的需求上这些工具兼容性便利性确实不敢恭维
    唯有 utools 的 json 编辑器官方插件功能不错兼容性也挺好,但就是连个文档都没有一切靠摸索门槛较高

    以上这些工具如果想从 json 中提取全量数据还都比较麻烦,搜过试过很多了 没办法满足需求才造轮子...
    pagxir
        6
    pagxir  
       308 天前 via Android
    windows 就直接用 node 就好了
    flyqie
        7
    flyqie  
       307 天前
    @faketemp #5

    go 好像好久之前就不支持 xp 了吧。。

    看 go.mod 里用的是 go 1.20 ?
    faketemp
        8
    faketemp  
    OP
       307 天前 via iPhone
    @flyqie 是的 因为用了泛型所以版本需要 1.18+ 不支持 xp 没啥同事绝大部分都用 win7ヾノ≧∀≦)o
    a90120411
        9
    a90120411  
       307 天前
    @xiangyuecn #2 可以分享一下解决方案吗?
    nerkeler
        10
    nerkeler  
       307 天前
    用 python 自带的 json 库就够了,再用 tkinter/pyqt 写个 GUI,开箱即用,我也写了个内网用的 json 格式化小工具,不过我们格式特殊,不通用。
    faketemp
        11
    faketemp  
    OP
       306 天前
    已升级兼容处理数据区域非数组结构而是一个对象的情况,如
    `{"part":1,"data":{"items":{"1":{"title":"one","name":"test1"},"2":{"title":"two","name":"test2"},{"3":{"title":"three","name":"test3"}}}}`

    这种结构遇到过多次但在线网站和各种工具均不支持解析提取,干脆自己兼容了
    `Json2Csv -k data.items test.json`即可提取全部"title/name"
    9yue
        12
    9yue  
       305 天前
    https://www.v2ex.com/t/951793 ,JS HTML 自带 UI 单文件版本,卷一下~~
    a90120411
        13
    a90120411  
       301 天前
    @xiangyuecn #2 有解决方案了吗?
    @faketemp
    wxf666
        14
    wxf666  
       297 天前
    @faketemp #8 既然都是 Win7 了,为啥 jq/dsq/fx 跑不起来呢?

    看了下,jq 还是纯 C 写的,xp 跑也没啥压力吧。。


    至于 jq 兼容性较差,json 识别出错,是 json 文件不标准吗?或者说是 json5 ?

    按理说,专门处理 json 的工具,识别不了 json ,是会贻笑大方的,应该不至于


    另外,有试过打包 python 环境吗?有大佬甚至能打包完整 PyQT5 环境,并分发。(不是 PyInstaller)

    链接: https://www.zhihu.com/question/48776632/answer/2336654649

    看起来,打包 pandas 应该也不会太难?
    faketemp
        15
    faketemp  
    OP
       297 天前 via iPhone
    @wxf666 感谢关注 不过你这些疑问应该自己没去测试过只是想当然觉得吧 ヾノ≧∀≦)o 事实上我尝试在几个不同版本系统测试过 包括 win7~win11 也包括精简版或完整版系统 这些工具的普适性兼容性确实表现欠佳 即使在 win11 上运行也遇到出现各种错误 参考 https://www.v2ex.com/t/883757#reply13 建议你有时间去测试一下就解惑了

    至于 json 文件是标准格式 只是几十兆比较大而已 是否贻笑大方不好说 但确实没几个工具能无报错识别和解析

    另外 python 打包不用挣扎 无论采用任何方法去打包都不优雅 写个 helloworld 打包也要 5 兆以上甚至十几兆 而且兼容多系统也很不便 golang 可以一键编译多平台 800k 单文件无依赖性能也超 n 倍 无任何一个理由要跑去打包生成更大更慢兼容更麻烦的 pandas 吧

    纸上得来终觉浅,绝知此事要躬行 建议你真的去测试一下,这样就了然了
    wxf666
        16
    wxf666  
       295 天前   ❤️ 1
    @faketemp #15 不知道你输入了什么命令,不太好猜出错原因。。


    我虚拟机装了个 Win XP 试了试,这些工具的最新版都还能正常运行:

    - jq ( v1.6 ,2.58 MB ,json 处理)
    - SQLite ( v3.42 ,1.09 MB ,小型数据库)
    - BusyBox ( v1.37 ,606 KB ,Linux Shell 风格脚本)
    - QuickJS ( v2021-03-27 ,863 KB ,支持 ES2020 的 js 引擎)

    有以上工具,足够编写很多便捷的小脚本了,也能拖动文件自动处理之类的。

    *( dsq 和 fx 确实在 Win XP 上运行不了,估计至少得 Win 7 。。)*


    试了试用这些工具导出 [行政区划第 5 级 json 数据( 80 MB )]( https://github.com/modood/Administrative-divisions-of-China/blob/master/dist/villages.json) 为 CSV ,确实还是你的 Json2Csv 工具快些。但总体而言,速度差异不是很大(对比如下,末尾附截图):

    | | Json2Csv | jq | SQLite | QuickJS |
    | :---: | :--------: | :----: | :----: | :-----: |
    | WinXP | (不支持) | 7.26 s | 5.67 s | 8.93 s |
    | Win10 | 3.72 s | 5.60 s | 4.26 s | 8.30 s |


    对了,如果要把这 5 级(省市县乡村)的 json 数据,根据各自的外键字段,串成 json 树(如下),有啥简单快捷的办法呢?

    ```json
    [
     {
      "code": "11",
      "name": "北京市",
      "children": [
       {
        "code": "1101",
        "name": "市辖区",
        "children": [
         "..."
        ]
       }
      ]
     },
     {
      "code": "12",
      "name": "天津市",
      "children": [
       "..."
      ]
     },
     "..."
    ]
    ```


    虚拟机里 WinXP 测试各工具导出 CSV 截图:

    ![]( )


    Win10 测试各工具导出 CSV 截图:

    ![]( )
    wxf666
        17
    wxf666  
       295 天前   ❤️ 1
    @faketemp #15 再试试 pandas 、dsq 、fx 这些,以及 dsq 提到的其他比较快的工具 octosql 、duckdb ( q 太大了,算了):

    - **pandas**:总计 5.24 s ,实际 pandas 只用 3.85 s 。看来确实有点重量级,不太适合日常小型数据处理。
    - **dsq**:5.30 s ,但是不支持 CSV 输出,是以 json 原样输出的。*(看时间统计,似乎是双线程?)*
    - **fx**:很久,且占了 4GB+ 内存,直接中断了。。*(好像也不支持 CSV 输出)*
    - **octosql**:不支持读取 JSON Array ,只能 JSON Object ?
    - **duckdb**:4.61 s ,和 SQLite 差不多。

    Shell 操作记录:

    ```shell
    ~/Downloads $ time py -c 'import time; import pandas as pd; begin = time.time(); pd.read_json(r"Y:\villages.json")[["code", "name"]].set_index("code").to_csv(r"Y:\out.csv"); print(f"{time.time() - begin:.2f}s")' && showCsv
    3.85s
    real 0m 5.24s
    user 0m 0.00s
    sys 0m 0.01s


    ~/Downloads $ time ./dsq.exe Y:/villages.json 'SELECT code, name FROM {}' > Y:/out.csv && showCsv
    real 0m 5.30s
    user 0m 8.81s
    sys 0m 1.50s
    619503 33905785 Y:/out.csv
    {"code":"659011502509","name":"十一连生活区"},
    {"code":"659011502510","name":"十二连生活区"},
    {"code":"659011502512","name":"五连生活区"}]


    ~/Downloads $ time ./fx.exe Y:/villages.json 'x.map(y => [y.code, y.name])' > Y:/out.csv && showCsv
    ^C


    ~/Downloads $ ./octosql.exe 'SELECT * FROM provinces.json'
    Error: typecheck error: couldn't create datasource: expected JSON object, got '[{"code":"11","name":"北京市"},{"code":"12","name":"天津市"},{"code":"13","name":"河北省"},{"code":"14","name":"山西省"},{"code":"15","name":"内蒙古自治区"},{"code":"21","name":"辽宁省"},{"code":"22","name":"吉 林省"},{"code":"23","name":"黑龙江省"},{"code":"31","name":"上海市"},{"code":"32","name":"江苏省"},{"code":"33","name":"浙江省"},{"code":"34","name":"安徽省"},{"code":"35","name":"福建省"},{"code":"36","name":"江西省"},{"code":"37","name":"山东省"},{"code":"41","name":"河南省"},{"code":"42","name":"湖北省"},{"code":"43","name":"湖南省"},{"code":"44","name":"广东省"},{"code":"45","name":"广西壮族自治区"},{"code":"46","name":"海南省"},{"code":"50","name":"重庆市"},{"code":"51","name":"四川省"},{"code":"52","name":"贵州省"},{"code":"53","name":"云南省"},{"code":"54","name":"西藏自治区"},{"code":"61","name":"陕西省"},{"code":"62","name":"甘肃省"},{"code":"63","name":"青海省"},{"code":"64","name":"宁夏回族自治区"},{"code":"65","name":"新疆维吾尔自治区"}]'


    ~/Downloads $ time ./duckdb.exe -csv :memory: "SELECT code, name FROM 'Y:/villages.json'" > Y:/out.csv && showCsv
    real 0m 4.61s
    user 0m 3.40s
    sys 0m 1.15s
    619504 22135235 Y:/out.csv
    659011502509,"十一连生活区"
    659011502510,"十二连生活区"
    659011502512,"五连生活区"
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3000 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 13:30 · PVG 21:30 · LAX 06:30 · JFK 09:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.