2012-06-16 31 views
8

我有這個問題試圖使用lxml獲取HTML文檔中的所有文本節點,但是我得到一個UnicodeEncodeError:'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128)。然而,當我試圖找出這個頁面的編碼類型(encoding = chardet.detect(response)['encoding'])時,它說它是utf-8。看起來很奇怪,單個頁面有utf-8和ascii。其實這個:獲取url時出現UnicodeEncodeError

fromstring(response).text_content().encode('ascii', 'replace') 

解決了這個問題。

這是我的代碼:

from lxml.html import fromstring 
import urllib2 
import chardet 
request = urllib2.Request(my_url) 
request.add_header('User-Agent', 
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)') 
request.add_header("Accept-Language", "en-us") 
response = urllib2.urlopen(request).read() 

print encoding 
print fromstring(response).text_content() 

輸出:

utf-8 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128) 

我能做些什麼來解決這個問題?請記住,我想用其他幾頁來做這件事,所以我不想單獨編碼。

UPDATE:

也許還有別的東西怎麼回事。當我在終端上運行這個腳本時,我得到了正確的輸出,但是當它在SublimeText中運行時,我得到了UnicodeEncodeError ...¿?

UPDATE2:

當我創建這個輸出文件,它也發生了。 .encode('ascii', 'replace')正在工作,但我想有一個更一般的解決方案。

問候

+1

在腳本內部是否有'print u「\ u00A9」'也會產生錯誤? – jfs

+0

是的。UnicodeEncodeError:'ascii'編解碼器無法對位置0中的字符u'\ xa9'進行編碼:序號不在範圍(128)中:-) –

+0

您可以將PYTHONIOENCODING設置爲任何編碼SublimeText所接受的字符。 – jfs

回答

5

你可以嘗試用repr()包裝你的字符串嗎? This article可能會有所幫助。

print repr(fromstring(response).text_content()) 
+0

這適用於Sublime Text和終端。我想這是一個工作方式。謝謝! –

0

根據您的第一次更新我要說的是,終端告訴Python來輸出UTF-8和SublimeText明確,預計ASCII。所以我認爲解決方案將在SublimeText中找到正確的設置。

但是,如果您無法更改SublimeText的預期效果,那麼最好使用encode函數,就像您在單獨的函數中所做的那樣。

def smartprint(text) : 
    if sys.stdout.encoding == None : 
     print text 
    else : 
     print text.encode(sys.stdout.encoding , 'replace') 

您可以使用此功能代替print。請記住,在SublimeText中運行時,程序的輸出與終端不同。由於replace重音字符將在SublimeText中運行此代碼時失去重音,例如é將顯示爲e

3

至於寫出來的文件,如你的編輯說,我會建議與編解碼器模塊打開文件:

import codecs 
output_file = codecs.open('filename.txt','w','utf8') 

我不知道SublimeText,但它似乎試圖讀取你的輸出爲ASCII,因此編碼錯誤。

+0

工作。謝謝! –

相關問題