Created
November 28, 2023 10:51
-
-
Save ecoopnet/7a2d91623be0b52bf6d7a77e4cb994c2 to your computer and use it in GitHub Desktop.
metaのアカウントセンターからダウンロードしたinstagramのjsonデータが変な形式なので、読める形に変換して書き出すやつ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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('\\\\', '\') | |
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