Kafayı yemek üzereydim. Farklı kaynaklardan veri çekip tek bir güzel JSON'da birleştiren otomasyon botumu yazmıştım. Her şey harika çalışıyordu, ta ki Türkçe karakterler ve emojiler devreye girinceye kadar. Botum, çöp karakterler (�) ve anlamsız dizilerle dolu bir canavara dönüştü.
Botun İlk Çalışma Anı ve Felaket Başlangıcı
Bir kaynak UTF-8, diğeri ISO-8859-9, bir başkası Windows-1254 ile geliyordu. Ben de saf gibi, tüm response'ları doğrudan string'e çevirip işliyordum. İlk başta fark etmedim bile, ta ki veritabanına kaydedip frontend'de "İstanbul" yerine "�stanbul" yazana kadar.
Debug Macerası ve "Meğerse" Anı
StackOverflow'da saatlerce aradım, "python encoding hell" diye. Meğerse sorun, her kaynağın [HEADER]'larında veya meta etiketlerinde farklı bir encoding belirtmesiymiş. Requests kütüphanesi bazen otomatik tahmin ediyor ama her zaman doğru değil. chardet kütüphanesini denedim, o da bazen "Ben de emin değilim abi" moduna girip saçmalıyordu.
Çözüm ve Artık Her Şeyi Açıkça Söyleyen Kod
En sonunda agresif bir strateji geliştirdim. Her kaynak için encoding'i zorla belirleyen, fallback'leri olan bir pipeline yazdım. Şaka gibi ama, bazı siteler meta'da "UTF-8" yazıp içeriği "ISO" gönderiyor. Onları da yakaladım.
Şimdi botum pürüzsüz çalışıyor. Ama o geçirdiğim iki günlük debug kabusu hâlâ aklımda. Siz de böyle encoding bataklığına saplandınız mı? Özellikle Türkçe içerikle uğraşırken daha temiz, daha Pythonic bir yolu var mı bu işin?
Bir kaynak UTF-8, diğeri ISO-8859-9, bir başkası Windows-1254 ile geliyordu. Ben de saf gibi, tüm response'ları doğrudan string'e çevirip işliyordum. İlk başta fark etmedim bile, ta ki veritabanına kaydedip frontend'de "İstanbul" yerine "�stanbul" yazana kadar.
Python:
# İşte o lanet olası saf kod:
raw_data = response.content # Bu bytes
text = raw_data.decode() # Varsayılan encoding ne acaba? :)
StackOverflow'da saatlerce aradım, "python encoding hell" diye. Meğerse sorun, her kaynağın [HEADER]'larında veya meta etiketlerinde farklı bir encoding belirtmesiymiş. Requests kütüphanesi bazen otomatik tahmin ediyor ama her zaman doğru değil. chardet kütüphanesini denedim, o da bazen "Ben de emin değilim abi" moduna girip saçmalıyordu.
En sonunda agresif bir strateji geliştirdim. Her kaynak için encoding'i zorla belirleyen, fallback'leri olan bir pipeline yazdım. Şaka gibi ama, bazı siteler meta'da "UTF-8" yazıp içeriği "ISO" gönderiyor. Onları da yakaladım.
Python:
def decode_safely(byte_data, declared_encoding=None):
encodings_to_try = []
if declared_encoding:
encodings_to_try.append(declared_encoding)
encodings_to_try.extend(['utf-8', 'iso-8859-9', 'windows-1254', 'cp1254'])
for enc in encodings_to_try:
try:
return byte_data.decode(enc, errors='strict')
except UnicodeDecodeError:
continue
# Son çare: hataları replace et, ama logla!
return byte_data.decode('utf-8', errors='replace')
Şimdi botum pürüzsüz çalışıyor. Ama o geçirdiğim iki günlük debug kabusu hâlâ aklımda. Siz de böyle encoding bataklığına saplandınız mı? Özellikle Türkçe içerikle uğraşırken daha temiz, daha Pythonic bir yolu var mı bu işin?