2013-04-05 63 views
1

我在BeautifulSoup4的UnicodeDammit模塊,這使一個字符串牢牢Unicode和也的忠實粉絲呢HTML轉義:保證Unicode或ASCII退避在Python 2.7

from bs4 import UnicodeDammit 
unicode_page = UnicodeDammit(raw_page, [suspected_encodings_if_any]).unicode_markup 

有情況下,即使但強大的Dammit失敗了,並返回一個空字符串。對於這些情況,我希望有一些回退到ascii。

Dammit使用chardet,所以沒有任何意義。 (Dammit也會尋找iconv_codec庫 - 任何人都有使用它的經驗?)退後到ascii的最佳方式是什麼?這嘗試失去的東西,但它似乎也工作:

def to_unicode_with_ascii_backoff(text): 
    if isinstance(text, unicode): 
     return text 
    else: 
     ud = UnicodeDammit(text).unicode_markup 
     if ud: 
      return ud 
     else: 
      return ''.join(i for i in text if ord(i) < 128) 
+0

字符集檢測不能可靠地完成 - 如果失敗是指這些情況,那麼您就無能爲力。 – Esailija 2013-04-06 09:14:05

+0

回覆上面的評論添加了回退位,謝謝。 – bahmait 2013-04-06 21:50:14

+0

'UnicodeDammit'可以在內部使用'chardet'。 「UnicodeDammit」的HTML主題的例子是什麼? 'bytestring.decode(encoding)'足以讓你獲得Unicode字符串(不需要多次編碼/解碼)。使用'isinstance(s,unicode)'而不是'type(s)is unicode'。用字符串調用'unicodedata.normalize()'是錯誤的。 – jfs 2013-04-08 17:59:40

回答

1

「最好」取決於您的應用程序。你可以遞增地改進你的功能:

def to_unicode_with_ascii_backoff(text): 
    u = UnicodeDammit(text).unicode_markup 
    return u if u or not text else text.decode('ascii', 'replace') 

它總是返回Unicode字符串,如果輸入不是字符串或Unicode字符串,則會引發錯誤。

+0

繼續感謝 - 從中​​學到了很多。還發現[unidecode](https://pypi.python.org/pypi/Unidecode),以便在必要時從unicode正確獲取ascii。最後需要刪除控制字符,在我的最後一行添加一個'if'來檢查'bad_chars = frozenset([0,1,2,3,4,5,6,7,8,11,12, 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31])' – bahmait 2014-08-08 04:52:39

+0

@CharlesS .:注:0x7f也是C控制字符 – jfs 2014-08-08 06:16:34