UnicodeEncodeError: 'ascii' kodek ne more kodirati znaka u'\xa0' na položaju 20: ordinal ni v območju(128)
Imam težave z enokodnimi znaki iz besedila, ki se pridobi z različnih spletnih strani (na različnih spletnih mestih). Uporabljam BeautifulSoup.
Težava je v tem, da napake ni vedno mogoče ponoviti; včasih deluje z nekaterimi stranmi, včasih pa se zmoti in vrže UnicodeEncodeError
. Preizkusil sem že vse, kar mi pride na misel, vendar še nisem našel ničesar, kar bi delovalo dosledno, ne da bi vrglo kakšno napako, povezano z Unicode.
Eden od delov kode, ki povzroča težave, je prikazan spodaj:
agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
Tukaj je sled za nekatere nize, ki se ustvarijo, ko se zažene zgornji delček:
Traceback (most recent call last):
File "foobar.py", line 792, in <module>
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)
Domnevam, da je to posledica tega, da so nekatere strani (ali natančneje, strani z nekaterih spletnih mest) lahko kodirane, medtem ko so druge nekodirane. Vse strani imajo sedež v Združenem kraljestvu in zagotavljajo podatke, namenjene britanski potrošnji, zato ni težav v zvezi z internalizacijo ali obravnavo besedila, ki ni napisano v angleščini.
Ali ima kdo kakšno idejo, kako to rešiti, da bi lahko to težavo KONZISTENTNO odpravil?
Preberi si Python Unicode HOWTO. Ta napaka je prvi primer.
V bistvu prenehajte uporabljati
str
za pretvorbo iz Unicode v kodirano besedilo / bajte.Namesto tega pravilno uporabite
.encode()
za kodiranje niza:ali pa v celoti delajte v enokodi.
To je klasična boleča točka unicode v Pythonu! Razmislite o naslednjem:
Do zdaj je vse v redu, toda če pokličemo str(a), poglejmo, kaj se bo zgodilo:
Oh dip, to ne bo nikomur koristilo! Napako odpravite tako, da bajte izrecno kodirate z .encode in pythonu poveste, kateri kodek naj uporabi:
Voil\u00E0!
Težava je v tem, da ko kličete funkcijo str(), python uporabi privzeto kodiranje znakov in poskuša kodirati bajte, ki ste mu jih posredovali, ki so v vašem primeru včasih predstavitve znakov unicode. Težavo odpravite tako, da pythonu poveste, kako naj ravna z nizom, ki ste mu ga dali, z uporabo .encode('whatever_unicode'). Večinoma vam bo zadostovala uporaba zapisa utf-8.
Za odlično predstavitev te teme si oglejte predavanje Neda Batchelderja na PyConu tukaj: http://nedbatchelder.com/text/unipain.html
Ugotovil sem, da je v večini mojih primerov veliko enostavneje odstraniti te znake: