Facebook JSON плохо закодирован - PullRequest
0 голосов
/ 24 апреля 2018

Я загрузил данные своего мессенджера Facebook (в вашей учетной записи Facebook перейдите к настройкам , , затем к Ваша информация Facebook , затем Загрузите информацию , затем создайте файл, в котором установлен хотя бы флажок Messages ), чтобы получить классную статистику

Однако существует небольшая проблема с кодировкой. Я не уверен, но похоже, что Facebook использовал плохую кодировку для этих данных. Когда я открываю его в текстовом редакторе, я вижу что-то вроде этого: Rados\u00c5\u0082aw. Когда я пытаюсь открыть его с помощью Python (UTF-8), я получаю RadosÅ\x82aw. Однако я должен получить: Radosław.

Мой скрипт на питоне:

text = open(os.path.join(subdir, file), encoding='utf-8')
conversations.append(json.load(text))

Я попробовал несколько наиболее распространенных кодировок. Пример данных:

{
  "sender_name": "Rados\u00c5\u0082aw",
  "timestamp": 1524558089,
  "content": "No to trzeba ostatnie treningi zrobi\u00c4\u0087 xD",
  "type": "Generic"
}

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Мое решение для анализа объектов использует parse_hook обратный вызов при загрузке / загрузке функция:

import json


def parse_obj(dct):
    for key in dct:
        dct[key] = dct[key].encode('latin_1').decode('utf-8')
        pass
    return dct


data = '{"msg": "Ahoj sv\u00c4\u009bte"}'

# String
json.loads(data)  
# Out: {'msg': 'Ahoj svÄ\x9bte'}
json.loads(data, object_hook=parse_obj)  
# Out: {'msg': 'Ahoj světe'}

# File
with open('/path/to/file.json') as f:
     json.load(f, object_hook=parse_obj)
     # Out: {'msg': 'Ahoj světe'}
     pass

Обновление:

Решение длясписок разбора со строками не работает.Итак, вот обновленное решение:

import json


def parse_obj(obj):
    for key in obj:
        if isinstance(obj[key], str):
            obj[key] = obj[key].encode('latin_1').decode('utf-8')
        elif isinstance(obj[key], list):
            obj[key] = list(map(lambda x: x if type(x) != str else x.encode('latin_1').decode('utf-8'), obj[key]))
        pass
    return obj
0 голосов
/ 25 апреля 2018

Я действительно могу подтвердить, что данные загрузки Facebook неправильно закодированы; Моджибаке .Исходные данные кодируются в кодировке UTF-8, но вместо этого были расшифрованы как латиница -1.Я обязательно подам отчет об ошибке.

Тем временем, вы можете исправить повреждение двумя способами:

  1. Декодировать данные как JSON, затем перекодировать любые строки как Latin-1, декодировать сновакак UTF-8:

    >>> import json
    >>> data = r'"Rados\u00c5\u0082aw"'
    >>> json.loads(data).encode('latin1').decode('utf8')
    'Radosław'
    
  2. Загрузить данные в двоичном виде, заменить все последовательности \u00hh байтом, который представляют последние две шестнадцатеричные цифры, декодировать как UTF-8 и затем декодироватьв формате JSON:

    import re
    from functools import partial
    
    fix_mojibake_escapes = partial(
         re.compile(rb'\\u00([\da-f]{2})').sub,
         lambda m: bytes.fromhex(m.group(1).decode()))
    
    with open(os.path.join(subdir, file), 'rb') as binary_data:
        repaired = fix_mojibake_escapes(binary_data.read())
    data = json.loads(repaired.decode('utf8'))
    

    Исходя из данных выборки, получается:

    {'content': 'No to trzeba ostatnie treningi zrobić xD',
     'sender_name': 'Radosław',
     'timestamp': 1524558089,
     'type': 'Generic'}
    
...