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