如果您不瞭解底層機制,很難解釋UnicodeError
。你真的應該讀的
在(非常小的)簡單地說,一個Unicode代碼點是一個抽象的「啄「代表一個字符。程序員喜歡使用這些字符串,因爲我們喜歡將字符串視爲一次一個字符。不幸的是,很久以前就頒佈了一個字符必須適合一個字節的內存,所以最多可以有256個不同的字符。簡單的英語很好,但不適用於其他任何東西。有一個代碼點的全局列表 - 其中成千上萬的代碼點 - 這是爲了保存每個可能的字符,但顯然它們不適合一個字節。
解決辦法:有碼點,使一個字符串有序列表之間的差,並且其編碼作爲字節序列。你必須清楚,每當你使用一個字符串,它應該在哪些這些形式。
要在窗體之間進行轉換,您可以.encode()
代碼點列表(一個Unicode字符串)作爲字節列表和.decode()
字節到代碼點列表中。爲此,您需要知道如何將代碼點映射到字節,反之亦然,這是編碼。如果你沒有指定,Python 2.x會猜測你的意思是ASCII。如果這種猜測是錯誤的,你會得到一個UnicodeError
。
請注意,Python 3.x在處理Unicode字符串方面要好得多,因爲字節和代碼點之間的區別更加明確。
整理。
編輯:我想我應該指出這是如何幫助。但你真的應該閱讀上面的鏈接!只要投入.encode()
s和.decode()
就是一種可怕的編碼方式,有一天你會被更糟糕的問題困擾。
無論如何,如果你通過你的殼做什麼步驟,你會看到
>>> from HTMLParser import HTMLParser
>>> text = "македонија"
>>> hparser = HTMLParser()
>>> text = hparser.unescape(text)
>>> text
u'\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0438\u0458\u0430'
我使用Python 2.7這裏
,所以這是一個Unicode字符串即Unicode代碼點的序列。我們可以將它們編碼爲一個常規字符串(即一個字節列表)像
>>> text.encode("utf-8")
'\xd0\xbc\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd0\xb8\xd1\x98\xd0\xb0'
但我們也可以選擇不同的編碼!
>>> text.encode("utf-16")
'\xff\xfe<\x040\x04:\x045\x044\x04>\x04=\x048\x04X\x040\x04'
您需要決定要使用的編碼。
你做了什麼錯了?那麼,並非每個編碼都能理解每個編碼點。特別是,"ascii"
編碼只能理解前256個!所以,如果你嘗試
>>> text.encode("ascii")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)
你只是得到一個錯誤,因爲你不能用ASCII編碼這些代碼點。
當你做req.write
,你試圖寫下請求的代碼點列表。但HTML請求不理解代碼點:它們只是使用ASCII。 Python 2會嘗試通過自動對ASCII字符串進行ASCII編碼來獲得幫助,如果它們確實是ASCII字符串,則很好,但如果它們不是這樣的話,則不會。因此你需要做req.write(hparser.unescape(text).encode("some-encoding"))
。
這是對unicode的一個很好的解釋,雖然我不確定它是否真的幫助OP從HTML實體轉到utf-8輸出。 – geoffspear 2012-04-16 11:05:52
@Wooble但OP的問題不是HTML實體!這是Unicode編碼(由UnicodeEncodeError證明)。 – katrielalex 2012-04-16 11:09:14
我需要html實體字符串,tnx的解釋,但我已經讀了很多字符表達式。 – badc0re 2012-04-16 11:15:48