2013-10-22 19 views
7

Bazı web sayfalarını ayrıştırmak için BeautifulSoup kullanıyorum. BazenGüzel Çorba ve Unicode Sorunları

Ben aşağıdaki gibi bir "unicode cehennem" hata çalıştırın: Bu makalenin kaynağı baktığımızda

TheAtlantic.com [http://www.theatlantic.com/education/archive/2013/10/why-are-hundreds-of-harvard-students-studying-ancient-chinese-philosophy/280356/]

Biz og bu bkz: tanım meta özelliği :

<meta property="og:description" content="The professor who teaches&nbsp;Classical Chinese Ethical and Political Theory claims, &quot;This course will change your life.&quot;" /> 
BeautifulSoup ayrıştırır, ben bakın

bu:

>>> print repr(description) 
u'The professor who teaches\xa0Classical Chinese Ethical and Political Theory claims, "This course will change your life."' 
Bu SO açıklama da anlaşılacağı gibi 363.210

ben UTF-8'e onu kodlayan çalışırsanız: https://stackoverflow.com/a/10996267/442650

>>> print repr(description.encode('utf8')) 
'The professor who teaches\xc2\xa0Classical Chinese Ethical and Political Theory claims, "This course will change your life."' 

Ben kontrol altında bütün unicode sorunları, hala oldukça ne oluyor anlamıyorum olduğunu sanıyordum Sadece zaman, bu yüzden birkaç soru ortaya koymak için gidiyorum:

1-

neden BeautifulSoup &nbsp; \xa0 için [latince charset boşluk karakteri] dönüştürmek ki? Bu sayfadaki karakter dizileri ve başlıklar UTF-8, BeautifulSoup'ın kodlama için bu verileri aldığını düşündüm. Neden bir <space> ile değiştirilmedi?

2- Dönüş için boşlukları normalleştirmenin ortak bir yolu var mı?

3- UTF8'e kodladığımda, \xa0\xc2\xa0 dizisi haline geldi?

unicodedata.normalize('NFKD',string) aracılığıyla nerede olmak istediğimi bulmama yardımcı olmak için her şeyi borularım - ama neyin yanlış olduğunu anlamak ve gelecekte bu gibi sorunlardan kaçınmak isterim.

cevap

21

Bir sorunla karşılaşmıyorsunuz. Her şey amaçlandığı gibi davranıyor.

&nbsp;, non-breaking space character numarasını belirtir. Bu bir boşluk ile değiştirilmez çünkü bir alanı temsil etmez; kırılmayan bir alanı temsil eder. Bir boşlukla değiştirmek, bilgiyi kaybeder: bu alanın meydana geldiği yerde, bir metin oluşturma motoru bir satır sonu koymamalıdır.

Kesilmeyen alan için Unicode kod noktası, Python'da bir Unicode dizesinde \xa0 olarak yazılan U + 00A0'dır. U + 00A0'nın UTF-8 kodlaması, onaltılık olarak, iki bayt dizisi C2 A0'dır veya bir Python dizisi gösterimi, \xc2\xa0'da yazılmıştır. UTF-8'de, 7 bit ASCII setinin dışındaki herhangi bir şey onu temsil etmek için iki veya daha fazla bayta ihtiyaç duyar. Bu durumda, en yüksek bit kümesi sekizinci bittir. Bu, iki bayt dizisi (ikili) 110xxxxx 10xxxxxx ile temsil edilebileceği anlamına gelir, burada x'ler kod noktasının ikili temsilinin bitleridir. A0 durumunda, bu 10000000 veya UTF-8, 11000010 10000000 veya C2 A0'da kodlandığında.

Birçok kişi (kuralları çöken olağan HTML boşluk olarak daraltılmış HTML olmayan boşluklar, ardışık boşluklar, sekmeler tüm ishal almak için HTML &nbsp; kullanın ve satırbaşları CSS white-space rules biri olmadıkça tek alan olarak yorumlanır olsun uygulandı), ama aslında bunun için tasarlanmamışlar; "Bay" gibi isimler gibi şeyler için kullanılacaklar.Miyagi ", burada" Bay "ve" Miyagi "arasında bir ara vermek istemediğiniz yerde, bu özel durumda neden kullanıldığından emin değilim; yorumlama kodunuzu değil, kaynağınızdaki bir sorunun yanıtını döndürür

Şimdi, düzen hakkında gerçekten bir şey umursamıyorsanız, metin düzeni algoritmalarının bunu kaydırılacak bir yer olarak seçip seçmeyeceğini düşünmüyorsunuz, ancak Bunu sadece normal bir alan olarak yorumlamak isteriz, NFKD'yi kullanarak normalize etmek oldukça mantıklı bir cevaptır (ya da ayrışmış aksanlara önceden oluşturulmuş aksanları tercih ederseniz NFKC) NFKC and NFKD normalizations harita karakterleri, esas olarak aynı semantik değeri temsil eden çoğu karakterin Çoğu bağlamlar genişletilir Örneğin, ligatürler genişletilir (ffi -> ffi), arkaik uzun karakterler karaktere dönüştürülür (ſ -> s), Romen rakam karakterleri genişletilir münferit harfleri (Ⅳ -> IV) ve kırılmayan alan normal bir alana dönüştürülür. Bazı karakterler için, NFKC veya NFKD normalizasyonu bazı durumlarda önemli olan bilgileri kaybedebilir: ℌ ve ℍ her ikisi de H'ye normalleşir, ancak matematiksel metinlerde farklı şeylere başvurmak için kullanılabilir.

+1

Vay. Çok teşekkür ederim Brian. Bu inanılmaz derecede detaylı bir cevap. 2bayt dizisini anlamadım ve bu benim diğer endişelerimin% 99'unu açıklıyor! BTW - Bu örnekte kullanılmasının nedeninin "CMS Cruft" (birkaç kez karşılaştığım bir şey) olduğundan oldukça eminim. –

+1

Evet, "CMS Cruft" HTML'yi ayrıştırmaya çalışırken her zaman bir sorun. –

İlgili konular