2014-10-11 80 views
1

我一直在嘗試最近學習Python,並且跟着這本書,Python for Data Analysis和使用Python 2.7與Canopy。在這本書中,他們提供了一個鏈接到我保存並分配到path變量的一些raw data。嘗試使用JSON文本文件轉換爲詞典列表後:Python/JSON:如何解析UnicodeDecodeError

records = [json.loads(line) for line in open(path)] 

我收到以下錯誤:

--------------------------------------------------------------------------- 
UnicodeDecodeError      Traceback (most recent call last) 
<ipython-input-17-b1e0b494454a> in <module>() 
----> 1 records = [json.loads(line) for line in open(path)] 

C:\Users\Marc\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.4.1.1975.win- x86_64\lib\json\__init__.pyc in loads(s, encoding, cls, object_hook, parse_float, parse_int,  parse_constant, object_pairs_hook, **kw) 
    336    parse_int is None and parse_float is None and 
    337    parse_constant is None and object_pairs_hook is None and not kw): 
--> 338   return _default_decoder.decode(s) 
    339  if cls is None: 
    340   cls = JSONDecoder 

C:\Users\Marc\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.4.1.1975.win- x86_64\lib\json\decoder.pyc in decode(self, s, _w) 
    363 
    364   """ 
--> 365   obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    366   end = _w(s, end).end() 
    367   if end != len(s): 

C:\Users\Marc\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.4.1.1975.win-x86_64\lib\json\decoder.pyc in raw_decode(self, s, idx) 
    379   """ 
    380   try: 
--> 381    obj, end = self.scan_once(s, idx) 
    382   except StopIteration: 
    383    raise ValueError("No JSON object could be decoded") 

UnicodeDecodeError: 'utf8' codec can't decode byte 0x92 in position 6: invalid start byte 

奇怪的是,這個工作在不同的電腦上,我認爲正在使用相同版本的Python。提前致謝。

+0

您的JSON數據不是UTF-8編碼的,它顯示。你是否100%確定它與你正在解碼的數據相同? – 2014-10-11 16:03:45

+0

即使使用相同版本的Python,取決於系統的區域設置,Python將嘗試使用的「默認」編碼也可能因計算機而異。這種行爲是故意的。 – skrrgwasme 2014-10-11 16:07:28

+0

@SLawson:這與默認(文件)編碼無關。這是Python 2,不會對文件數據進行解碼。 'json'模塊會解碼,因爲JSON標準指定了可接受的(有限的)數量的編碼。 – 2014-10-11 16:09:55

回答

2

有問題的數據包含一個編碼爲UTF-8的U+2019 RIGHT SINGLE QUOTATION MARK字符。但是您使用了複製粘貼來保存數據,而不是直接將文本保存到磁盤。

在這樣做時,某處的數據解碼的方式,然後再編碼,到Windows代碼頁1252:

>>> u'\u2019'.encode('cp1252') 
'\x92' 

換句話說,你的數據文件是不一樣。它可能包含相同的數據,但使用不同的編碼。

JSON標準狀態數據需要爲encoded to UTF-8, UTF-16 or UTF-32,UTF-8爲默認值,這就是Python json模塊如果不給它編碼就會用到的東西。由於您正在爲其提供CP-1252數據,因此解碼失敗。