UnicodeDecodeError:'utf8'编解码器无法解码位置3131中的字节0x80:无效的起始字节

wan*_*ppy 9 json ascii utf-8 python-2.7 python-unicode

我试图使用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
Run Code Online (Sandbox Code Playgroud)

结果我得到了:

    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
Run Code Online (Sandbox Code Playgroud)

我查看了类似问题的所有答案,并提出了这个代码,它上次工作了.我不知道为什么它现在不工作......我将不胜感激任何帮助!

小智 28

在我的情况下(mac os),我的数据文件夹中有.DS_store文件,这是一个隐藏的自动生成的文件,它导致了这个问题.删除后我能解决问题.

  • 谢谢宋!在 Mac 操作系统上对我来说也是同样的问题,我最终忽略了代码中的文件,因为它将由操作系统重新生成,而且我不确定永久删除它有多安全...... (3认同)
  • 在这种情况下,您可以使用“find”。-name '.DS_Store' -type f -delete` 以递归方式删除当前目录中的所有此类文件。请参阅 https://jonbellah.com/articles/recursively-remove-ds-store (3认同)

Ala*_*ack 12

它没有帮助,这让sys.setdefaultencoding('utf-8')事情更加混乱 - 这是一个讨厌的黑客,你需要从你的代码中删除它.有关更多信息,请参阅/sf/answers/2406527371/

发生错误是因为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)
Run Code Online (Sandbox Code Playgroud)

io模块还提供Universal Newlines.这意味着\r\n被检测为换行符,因此您不必注意它们.


Jac*_*ern 11

对于由于错误消息而遇到此问题的其他人,当我以文本模式而不是二进制模式打开文件时,我在尝试打开 pickle 文件时遇到了此错误。

这是原来的代码:

import pickle as pkl
with open(pkl_path, 'r') as f:
    obj = pkl.load(f)
Run Code Online (Sandbox Code Playgroud)

这修复了错误:

import pickle as pkl
with open(pkl_path, 'rb') as f:
    obj = pkl.load(f)
Run Code Online (Sandbox Code Playgroud)