Skip to content

Instantly share code, notes, and snippets.

@ecoopnet
Created November 28, 2023 10:51
Show Gist options
  • Save ecoopnet/7a2d91623be0b52bf6d7a77e4cb994c2 to your computer and use it in GitHub Desktop.
Save ecoopnet/7a2d91623be0b52bf6d7a77e4cb994c2 to your computer and use it in GitHub Desktop.
metaのアカウントセンターからダウンロードしたinstagramのjsonデータが変な形式なので、読める形に変換して書き出すやつ
#!/usr/bin/env python3
import json
# metaのアカウントセンターからダウンロードしたinstagramのjsonデータが変な形式なので、読める形に変換して書き出す。
# (なぜか非 ascii 文字列が \uxxx がバイトコードになってて普通には読めない…)
# 元jsonファイル
json_file = "~/Downloads/posts_1.json"
out_file = json_file + ".out.json"
# json.loads が勝手にエスケープ解釈しないように、
# \u0000〜の先頭文字列をこの文字列に置換して待避しておくための待避文字列。
# 元の json に確実に存在しない文字列で、かつ、json.loads が勝手にエスケープ解釈しない文字列なら何でもいい。
escapedSymbol = "<<ENC>>>"
def decode_unicode_escapes(data):
""" JSONデータ内の文字列に対してUnicodeエスケープシーケンスをデコードする再帰関数 """
if isinstance(data, str):
# 待避の解除
data = data.replace(escapedSymbol, '\\u')
# \u0011 のようなバイトコードエスケープシーケンスをデコード
bin = bytes(data, 'utf-8')
return bin.decode('unicode_escape').encode('latin1').decode('utf-8')
elif isinstance(data, list):
return [decode_unicode_escapes(item) for item in data]
elif isinstance(data, dict):
return {key: decode_unicode_escapes(value) for key, value in data.items()}
else:
return data
def main():
# JSONデータを読み込む
with open(json_file, "r") as f:
data = f.read()
# json.loadsにそのまま渡すと1バイトずつエスケープされていた場合に変に解釈されてしまうので、\u0000〜の文字列を自動デコードしないように待避しておく。
data = data.replace('\\u', escapedSymbol)
# "\\" (非エスケープのバックスラッシュ)があると誤ってエスケープしてしまうので、html文字としてエスケープしておく。
data = data.replace('\\\\', '&#92;')
json_data = json.loads(data)
# デコード処理を適用
decoded_data = decode_unicode_escapes(json_data)
# 結果を出力
with open(out_file, "w") as f:
f.write(json.dumps(decoded_data, indent=2, ensure_ascii=False))
# print(json.dumps(decoded_data, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment