UnicodeDecodeError: кодек "utf8" не может декодировать байт 0x80 в позиции 3131: недопустимый начальный байт

Я пытаюсь прочитать данные Twitter из файла JSON с помощью Python 2.7.12.

Код, который я использовал, такой:

    import json
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')

    def get_tweets_from_file(file_name):
        tweets = []
        with open(file_name, 'rw') as twitter_file:
            for line in twitter_file:
                if line != '\r\n':
                    line = line.encode('ascii', 'ignore')
                    tweet = json.loads(line)
                    if u'info' not in tweet.keys():
                        tweets.append(tweet)
    return tweets

Результат я получил:

    Traceback (most recent call last):
      File "twitter_project.py", line 100, in <module>
        main()                  
      File "twitter_project.py", line 95, in main
        tweets = get_tweets_from_dir(src_dir, dest_dir)
      File "twitter_project.py", line 59, in get_tweets_from_dir
        new_tweets = get_tweets_from_file(file_name)
      File "twitter_project.py", line 71, in get_tweets_from_file
        line = line.encode('ascii', 'ignore')
    UnicodeDecodeError: 'utf8' codec can't decode byte 0x80 in position 3131: invalid start byte

Я просмотрел все ответы по схожим вопросам и придумал этот код, и он работал в прошлый раз. Я понятия не имею, почему это не работает сейчас... Буду признателен за любую помощь!

5 ответов

Решение

Это не поможет, что у вас есть sys.setdefaultencoding('utf-8'), что еще больше сбивает с толку - это неприятный хак, и вам нужно удалить его из своего кода. См. /questions/23253360/pochemu-myi-ne-dolzhnyi-ispolzovat-syssetdefaultencodingutf-8-v-skripte-py/23253374#23253374 для получения дополнительной информации.

Ошибка происходит потому, что line это строка, и вы звоните encode(), encode() имеет смысл, только если строка является Unicode, поэтому Python сначала пытается преобразовать его в Unicode, используя кодировку по умолчанию, которая в вашем случае UTF-8, но должно быть ASCII, В любом случае, 0x80 не является допустимым ASCII или UTF-8, поэтому не работает.

0x80 действует в некоторых наборах символов. В windows-1252/cp1252 его ,

Хитрость в том, чтобы понять кодировку ваших данных на всем протяжении вашего кода. На данный момент вы оставляете слишком много, чтобы случайно. Типы Unicode String - это удобная функция Python, которая позволяет декодировать закодированные строки и забывать о кодировании до тех пор, пока вам не понадобится записать или передать данные.

Использовать io Модуль для открытия файла в текстовом режиме и декодирования файла по мере его поступления - не более .decode()! Вы должны убедиться, что кодировка ваших входящих данных соответствует. Вы можете либо перекодировать его внешне, либо изменить кодировку в вашем скрипте. Вот я установил кодировку windows-1252,

with io.open(file_name, 'r', encoding='windows-1252') as twitter_file:
    for line in twitter_file:
        # line is now a <type 'unicode'>
        tweet = json.loads(line)

io Модуль также предоставляет Universal Newlines. Это означает \r\n обнаруживаются как новые строки, поэтому вам не нужно следить за ними.

В моем случае (mac os) в папке с данными был файл.DS_store, который был скрытым и автоматически сгенерированным файлом, и это вызвало проблему. Я смог решить проблему после ее удаления.

Для других, кто сталкивается с этим вопросом из-за сообщения об ошибке, я столкнулся с этой ошибкой, пытаясь открыть файл рассола, когда я открыл файл в текстовом режиме, а не в двоичном режиме.

Это был исходный код:

      import pickle as pkl
with open(pkl_path, 'r') as f:
    obj = pkl.load(f)

И это исправило ошибку:

      import pickle as pkl
with open(pkl_path, 'rb') as f:
    obj = pkl.load(f)

Я получил аналогичную ошибку, случайно попытавшись прочитать файл паркета как csv

pd.read_csv(file.parquet)

pd.read_parquet(file.parquet)

Ошибка возникает, когда вы пытаетесь прочитать твит, содержащий предложение вроде

"@Mike http: \ www.google.com \ A8 & ^) ((&() как есть &^%()( you ". Вместо этого нельзя прочитать как строку, вы должны считать ее необработанной строкой, но конвертировать к сырой строке все еще дает ошибку, так что я лучше я предлагаю вам

прочитайте файл json примерно так:

import codecs
import json
    with codecs.open('tweetfile','rU','utf-8') as f:
             for line in f:
                data=json.loads(line)
                print data["tweet"]
keys.append(data["id"])
            fulldata.append(data["tweet"])

который получит загрузку данных из файла json.

Вы также можете записать его в CSV с помощью Pandas.

import pandas as pd
output = pd.DataFrame( data={ "tweet":fulldata,"id":keys} )
output.to_csv( "tweets.csv", index=False, quoting=1 )

Затем прочитайте из csv, чтобы избежать проблем с кодированием и декодированием.

надеюсь, это поможет вам решить вашу проблему.

Midhun

Другие вопросы по тегам