Facebook や Instagram のデータのダウンロードで JSON の日本語

FacebookInstagram の投稿など、(個人)データをまとめてダウンロードすることが出来る、データ形式JSON もあるのだけど、その日本語が読めない。
日本語というか非ASCIIというかそういう文字。

  • Facebook - アカウント - 設定とプライバシー - 設定
    • あなたのFacebook情報 - 個人データをダウンロード - コピーをリクエスト - フォーマット - JSON
  • Instagram - 設定
    • プライバシーとセキュリティ - データのダウンロード - ダウンロードをリクエスト - 情報フォーマット - JSON

ダウンロードはこの辺から。

猫廼舎。2019年09月28日(土) 15:00:59

それで、この辺の投稿

フェイスブック
https://www.facebook.com/hi.shimura.9/posts/2627556467311596

インスタグラム
https://www.instagram.com/p/B28a5ANHUI6/?igshid=1qe54csg90kch

ちなみにツイッターの投稿はこちら
https://twitter.com/hs9587/status/1177825511520788485

それはこういう文字です

irb(main):009:0> "猫廼舎。".force_encoding('ASCII')
=> "\xE7\x8C\xAB\xE5\xBB\xBC\xE8\x88\x8E\xE3\x80\x82"

それが上記でダウンロードしたなかで、

フェイスブック

  {
    "timestamp": 1569650461,
    "attachments": [
      {
        "data": [
          {
            "media": {
              "uri": "photos_and_videos/InstagramPhotos_DG0b8PZadQ/71746085_2627556473978262_1018468751701442560_n_2627556467311596.jpg",
              "creation_timestamp": 1569650461,
              "title": "Instagram Photos",
              "description": "\u00e7\u008c\u00ab\u00e5\u00bb\u00bc\u00e8\u0088\u008e\u00e3\u0080\u0082"
            }
          }
        ]
      }
    ]
  },


インスタグラム

  {
    "media": [
      {
        "uri": "media/posts/201909/70725295_131712588184345_6958651618331221860_n_18004788103249812.jpg",
        "creation_timestamp": 1569650456,
        "media_metadata": {
 …… (写真のメタデータ少々)
        },
        "title": "\u00e7\u008c\u00ab\u00e5\u00bb\u00bc\u00e8\u0088\u008e\u00e3\u0080\u0082"
      }
    ]
  },

こんな感じ。
(それそれ一部切り出し、なかの uri の記述はそれぞれの同梱データでの画像ファイル名)

日本語文字列

というわけで

"\u00e7\u008c\u00ab\u00e5\u00bb\u00bc\u00e8\u0088\u008e\u00e3\u0080\u0082"

「猫廼舎。」

JSON なら UTF-8 のはずなんだけどそうじゃない、手近の JSONパーサはそう思って変換して読めなくなってしまう。(Rubyjsonライブラリです)

この辺参考に文字を読みます

UTF-8 の16進表記を2桁ずつにして「\u00」に繋げてるみたい、どういう形式(名前)のエンコーディングなんだろう。

というわけで、encoding: 'ascii' で読み、そのように変換します、Ruby です。

irb(main):026:0> neko
=> "              \"description\": \"\\u00e7\\u008c\\u00ab\\u00e5\\u00bb\\u00bc\\u00e8\\u0088\\u008e\\u00e3\\u0080\\u0082\"\n"
irb(main):027:0> neko.encoding
=> #<Encoding:US-ASCII>
irb(main):028:0> neko.gsub(/\\u00([a-f0-9]{2})/m){ "#{$1.to_i(16).chr}"}.force_encoding('UTF-8')
=> "              \"description\": \"猫廼舎。\"\n"