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

时间:2016-07-22 04:11:42

标签: json python-2.7 utf-8 ascii 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

结果我得到了:

    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

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

3 个答案:

答案 0 :(得分:22)

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

答案 1 :(得分:12)

你有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模块还提供通用换行符。这意味着\r\n被检测为换行符,因此您无需关注它们。

答案 2 :(得分:-2)

当您尝试阅读包含

之类的句子的推文时,会发生错误

&#34; @Mike http:\ www.google.com \ A8&amp; ^)((&amp; ()&amp; ^%()(你&#34;。不能作为String读取,而是假设您将其作为原始String读取。 但转换为原始字符串仍然给出错误,所以我建议你更好

读取类似这样的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文件中获取数据加载。

您也可以使用Pandas将其写入csv。

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

然后从csv读取以避免编码和解码问题

希望这能帮助您解决问题。

Midhun