2013-05-10 55 views
3

我正在嘗試遵循Data Sci的課程介紹。但我遇到了一個問題,同時試圖解析來自twitter的json響應解析推文json中的新人錯誤UnicodeEncodeError:'charmap'編解碼器無法編碼位置13-63中的字符:字符映射到<undefined>

我想從以下格式的json中檢索文本。

{u'delete': {u'status': {u'user_id_str': u'702327198', u'user_id': 702327198, u'id': 332772178690981889L, u'id_str': u'332772178690981889'}}}, {u'delete': {u'status': {u'user_id_str': u'864736118', u'user_id': 864736118, u'id': 332770710667792384L, u'id_str': u'332770710667792384'}}}, {u'contributors': None, u'truncated': False, **u'text'**: u'RT @afgansyah_reza: Lagi ngantri. Ada ibu2 &amp; temennya. "Ih dia mukanya mirip banget sama Afgan.", trus ngedeketin gw, "Tuh kan.. Mirip bang\u2026', u'in_reply_to_status_id': None, u'id': 332772350640668672L, u'favorite_count': 0, ....... ] 

這裏是我使用它的代碼:

def hw(): 
    data = [] 
    count=0 
    with open('output.txt') as f: 
     for line in f: 
      encoded_string = line.strip().encode('utf-8') 
      data.append(json.loads(encoded_string)) 

    print data# generates the input to next block 
    for listval in data:#individual block 
     if "text" in listval: 
      print listval["text"] 
     else: 
      continue 

不過,我得到以下輸出和錯誤,當我運行它

RT @afgansyah_reza: Lagi ngantri. Ada ibu2 &amp; temennya. "Ih dia mukanya mirip banget sama Afgan.", trus ngedeketin gw, "Tuh kan.. Mirip bang… 
RT @Dimaz_CSIX: Kolor pakek pita #laguharlemshake 
Traceback (most recent call last): 
    File "F:\ProgrammingPoint\workspace-new\PyTest\tweet_sentiment.py", line 41, in <module> 
    main() 
    File "F:\ProgrammingPoint\workspace-new\PyTest\tweet_sentiment.py", line 36, in main 
    hw() 
    File "F:\ProgrammingPoint\workspace-new\PyTest\tweet_sentiment.py", line 23, in hw 
    print listval["text"] 
    File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode 
    return codecs.charmap_encode(input,errors,encoding_table) 
UnicodeEncodeError: 'charmap' codec can't encode characters in position 13-63: character maps to <undefined> 

我是一個新人,以Python和任何幫助,將不勝感激。

+2

順便說一句,學習Python 3.3而不是2.7的好處之一就是這個東西要容易得多。 (3.x強迫你比2.x早得多處理Unicode,但是因爲你已經用2.x運行了它,這不是什麼壞處。) – abarnert 2013-05-11 00:22:36

回答

8

所有的轉換等都是正確的。問題只是試圖print它來標準輸出。

(通常情況下,你遇到了重音,東亞等字符的問題;這似乎是與省略號,但它是同樣的問題。)

如果你正在運行此在終端窗口(DOS提示符等)中,您只能打印終端字符集可以處理的字符。因此,例如,在配置爲'cp1252'的Windows盒子(如您的)上,您不能打印非Latin-1 /非Latin-15 /非ANSI字符。

(在早期版本的Python,還有另外一個問題了Python可能無法正確猜出你的終端最佳編碼,並堅持你,說,'ascii'即使它能夠處理utf-8,或至少cp1252。你可以找出Python爲stdout猜測的編碼是sys.stdout.encoding如果這是錯誤的,你可以明確地修正它。)

但是如果你的終端不是UTF-8(而且不是),你需要告訴它如何處理它無法表示的字符。您可以encode串用明確errors參數,只要你print他們,就像這樣:

print u.encode(sys.stdout.encoding, 'replace') 

...或各種其他的東西。但是如果你想在一個地方解決這個問題,你想改變打印的默認錯誤處理程序。

不幸的是,在Python 2.7中,雖然sys.stdout確實有errors屬性,但它是隻讀的。解決這個問題的方法之一是用原來的sys.stdout(或其底層文件句柄或其他等效物)周圍的包裝來替換它。例如:

>>> u = 'RT @afgansyah_reza: Lagi ngantri. Ada ibu2 &amp; temennya. "Ih dia mukanya mirip banget sama Afgan.", trus ngedeketin gw, "Tuh kan.. Mirip bang\xe2\x80\xa6'.decode('utf8') 
>>> print u 
UnicodeEncodeError: 'charmap' codec can't encode characters in position 13-63: character maps to <undefined> 
>>> sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout, errors='replace') 
>>> print u 
RT @afgansyah_reza: Lagi ngantri. Ada ibu2 &amp; temennya. "Ih dia mukanya mirip banget sama Afgan.", trus ngedeketin gw, "Tuh kan.. Mirip bang? 

欲瞭解更多信息,請閱讀2.x Unicode HOWTO,並在print的文檔。他們期望您知道unicode對象是一個字符串,因此它不會被print轉換,而是按原樣傳遞給write。所以,訣竅是在sys.stdout.write中放置某種包裝,它將按原樣寫入str對象,但對象編碼方式不同。codecsio可以爲你做到這一點,但codecs更向後兼容(和io更向前兼容,但這並沒有太大的區別,因爲3.x處理Unicode的方式非常不同)。

+0

謝謝你的回覆。當我試圖將'sys.stdout.errors ='replace''追加到我的代碼中時,出現以下錯誤:'sys.stdout.errors ='replace'' TypeError:readonly attribute'。有什麼想法嗎? – KodeSeeker 2013-05-10 23:44:50

+0

糟糕,那是_did_以前是隻讀的。我認爲這是在2.7.0更改,但是...我想不是。讓我更新答案。 – abarnert 2013-05-10 23:51:32

0

您的json.loads調用將UTF-8編碼的json轉換回Python Unicode字符串。當您打印它時,它會嘗試將文本轉換爲您環境的默認編碼,cp1252.py參考明確指出的是Windows代碼頁1252.您必須決定輸出格式並在打印之前進行編碼。如果你想要cp1252,給它一個錯誤處理程序,而不是默認的'strict'。

http://docs.python.org/2/howto/unicode.html擁有完整的文檔,包括各種錯誤處理程序的可能性。

5

如果您正在使用的PyDev Eclipse插件嘗試將Windows的>首選項 - >常規 - >工作區,並選擇在在文本文件編碼左下角 - >選擇其他= UTF-8

也許工作。

相關問題