web-dev-qa-db-ja.com

UnicodeDecodeError: 'utf8'コーデックは位置3131のバイト0x80をデコードできません:無効な開始バイト

python 2.7.12。を使用してjsonファイルからTwitterデータを読み取ろうとしています。

私が使用したコードは次のとおりです。

    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

私は同様の問題からすべての答えを調べ、このコードを思いついたが、それは前回働いた。なぜ今動作していないのか、私には何の手掛かりもありません...助けていただければ幸いです!

9
wannabhappy

sys.setdefaultencoding('utf-8')を持っているのは役に立ちません。これはさらに物事を混乱させています-これは厄介なハックであり、コードから削除する必要があります。詳細については、 https://stackoverflow.com/a/34378962/1554386 を参照してください

lineは文字列であり、encode()を呼び出しているため、エラーが発生しています。 encode()は文字列がUnicodeの場合にのみ意味があるため、Pythonはデフォルトのエンコードを使用してUnicodeを最初に変換しようとします。これはUTF-8ですが、ASCIIいずれにしても、0x80は有効ではありませんASCIIまたはUTF-8なので失敗します。

0x80は、一部の文字セットで有効です。 windows-1252/cp1252では、です。

ここでのコツは、コード全体でデータのエンコードを理解することです。現時点では、チャンスを逃しすぎています。 Unicode文字列型は便利な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が改行として検出されることを意味するため、それらを監視する必要はありません。

12

私の場合(mac os)、データフォルダーに.DS_storeファイルがあり、これは非表示の自動生成ファイルであり、問​​題の原因でした。私はそれを削除した後、問題を修正することができました。

27
Sung-Ho_Ahn