我正在尝试使用 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
我浏览了类似问题的所有答案,并提出了这段代码,并且上次它有效。我不知道为什么它现在不起作用。
就我而言(mac os),我的数据文件夹中有 .DS_store 文件,这是一个隐藏的自动生成的文件,它导致了问题。删除后我能够解决问题。
拥有
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
被检测为换行符,因此您不必注意它们。
对于由于错误消息而遇到此问题的其他人,当我以文本模式而不是二进制模式打开文件时,我在尝试打开 pickle 文件时遇到了此错误。
这是原始代码:
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)
我无意中尝试将 parquet 文件读取为 csv 时遇到了类似的错误
pd.read_csv(file.parquet)
pd.read_parquet(file.parquet)
我刚刚在一个奇怪的情况下遇到了这个错误。我正在处理共享数据,
.json
文件实际上是泡菜。因此,对我来说解决这个问题的是:
with open("pickled_file_with_bad_extension.json", "rb") as f:
data = pickle.load(f)
当您尝试阅读包含类似句子的推文时,会发生错误
"@Mike http:\www.google.com \A8&^)((&() how are&^%()( 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 文件加载数据。
您还可以使用 Pandas 将其写入 csv。
import pandas as pd
output = pd.DataFrame( data={ "tweet":fulldata,"id":keys} )
output.to_csv( "tweets.csv", index=False, quoting=1 )
然后从csv中读取,避免编码解码问题
希望这能帮助您解决问题。
米敦