Python Türkçe Karakter Sorunu: Encoding Nasıl Düzeltilir?

Yayın tarihi:

13 dk okuma

Acar Diveroli
Yazar: Acar Diveroli
Üç izometrik katman: altta C4 B1 baytları, ortada mavi UTF-8 codec, üstte U+0131; solda kesik çizgili ISO-8859-1 levhası

Bir betik, Türkiye'deki eski bir belediye sitesinden ihale ilanlarını topluyor. Tarayıcıda başlık Çankırı İhale İlanı diye görünüyor, betik ise Çankýrý Ýhale Ýlaný yazdırıyor. Betiğin bir Windows dizüstü bilgisayarda kaydettiği liste de Linux sunucuda açılırken 'utf-8' codec can't decode byte 0xc7 in position 0: invalid continuation byte hatası veriyor. İki sorunun sebebi aynı: baytlar bir kod tablosuyla yazılmış, başka bir kod tablosuyla okunmuş.

Bu yazıda sorunu göründüğü her yerde düzeltiyoruz: kaynak dosyalar, open(), Windows konsolu, Requests ve Beautiful Soup ile çekilen sayfalar ve Excel için yazılan CSV dosyaları. Bozulmuş metni nasıl okuyup onaracağınızı da gösteriyoruz. Aşağıdaki her bayt değeri ve hata mesajı, Python 3.13 ile yaptığımız kendi denemelerimizden geliyor.

Python'da str ile bytes arasındaki fark nedir?

str karakterleri tutar ve her karakterin bir Unicode kod noktası vardır: Türkçedeki noktasız ı U+0131, é ise U+00E9'dur. Disk ve ağ yalnızca bayt saklar; metin dışarı çıkarken kodlanır (encode), içeri girerken çözülür (decode). Hangi baytın hangi karakteri temsil ettiğini kodlama (encoding) belirler, Python da bu eşleme tablolarına codec der. UTF-8'de ı iki bayttır: C4 B1. Eski Türkçe Windows kod sayfası windows-1254'te ise tek bayttır: FD. Batı Avrupa dilleri için kullanılan cp1252'de ve ISO-8859-1'de ı hiç yoktur.

Yazan ile okuyan farklı kodlama kullandığında baytlar sağlam kalır ama harfler değişir. Buna mojibake denir ve çoğu zaman geri alınabilir.

Bir karakter nasıl başka bir karaktere dönüşür?

Her kodlama hatası aynı adımları izler:

  1. Metniniz Unicode'dur. Python'da "Çankırı" yedi kod noktasıdır.
  2. A kodlamasıyla kodlanır. Türkçe Windows bu metni cp1254 ile C7 61 6E 6B FD 72 FD olarak yazar.
  3. Yalnızca baytlar taşınır. Bir dosya, bir HTTP gövdesi ya da bir pipe, A kodlamasını kendiliğinden bildirmez; bu bilgiyi ancak bir header, bir BOM ya da bir <meta> etiketi ekler.
  4. Biri B kodlamasıyla çözer. ISO-8859-1 FD baytını ý harfine eşler ve ortaya Çankýrý çıkar. UTF-8 ise C7 61 dizisini bir karakter olarak okuyamaz ve UnicodeDecodeError fırlatır.
  5. Çıktı yeniden kodlanır. print() ve write() konsolun ya da dosyanın kodlamasını kullanır; o kodlamada bulunmayan bir karakter UnicodeEncodeError verir.

Hangi yönün bozulduğunu traceback söyler.

Bozuk metin size ne söyler?

Bozulmanın biçimi, hangi iki kodlamanın karıştığını gösterir.

GördüğünüzGerçek metinNe olduNe yapmalı
café, ü, ı, ÅŸcafé, ü, ı, şUTF-8 baytları (C3 A9, C4 B1) cp1252 ya da ISO-8859-1 ile çözülmüşBaytları UTF-8 olarak çözün ya da metni onarın (aşağıda)
ý, þ, ð, Ýı, ş, ğ, İwindows-1254 baytları (FD, FE, F0, DD), Requests'in varsayılanı olan ISO-8859-1 ile çözülmüşr.encoding = "cp1254" ayarlayın ya da Beautiful Soup'a r.content verin
ş yerine ţşTahmin, Türkçe bir sayfa için windows-1250'yi seçmişO sitenin kodlamasını sabitleyin
ASCII dışındaki herhangi bir harfBaytlar errors="replace" ile UTF-8 olarak çözülmüşMetinde kayboldu; ham baytları yeniden çözün
?Herhangi bir harfMetin, o harfi içermeyen bir kodlamaya errors="replace" ile kodlanmışKayboldu; UTF-8 ile yazın
Boş bir kutuDoğru harfFontta o harfin glifi yok (PDF, eski terminal)Kodlamayı değil fontu değiştirin

Python 3'te # -*- coding: utf-8 -*- satırı hâlâ gerekli mi?

Hayır. PEP 3120 Python 3.0 ile kaynak dosyaların varsayılan kodlamasını UTF-8 yaptı; bu satır Python 2'den kalmadır. .py dosyanızdaki metin sabitleri hâlâ bozuluyorsa editörünüz dosyayı eski bir kod sayfasıyla (Windows'ta "ANSI") kaydetmiştir; dosyayı UTF-8 olarak kaydedin. u"" öneki ve codecs.open() gibi diğer Python 2 öğütlerine de gerek yok.

Dosya okurken ve yazarken encoding nasıl belirtilir?

encoding değerini her seferinde verin: open("cities.txt", "w", encoding="utf-8"). Verilmezse Python 3.13 Windows'ta ANSI kod sayfasını kullanır. Türkçe Windows makinemizde locale.getpreferredencoding(False) cp1254 döndürdü ve düz bir open("cities.txt", "w") çağrısı Çankırı sözcüğünü C7 61 6E 6B FD 72 FD olarak yazdı. İngilizce Windows ise içinde ı olmayan cp1252'yi kullanır; aynı yazma işlemi orada 'charmap' codec can't encode character 'ı' hatasıyla durur.

Size gelen dosyalarda, dosyanın yazıldığı kodlamayı kullanın: eski Türkçe Windows ve Excel çıktıları için cp1254, Batı Avrupa dillerindekiler için cp1252, Arapça ve Farsça için cp1256. Sığmayan baytlara ne olacağına errors argümanı karar verir:

  • Varsayılan strict hata fırlatır. Doğru kodlamayı ararken istediğiniz de budur.
  • replace her bozuk baytın yerine koyar, böylece hasarın nerede olduğunu görürsünüz.
  • backslashreplace bozuk baytları \xfd biçiminde görünür bırakır.
  • ignore onları sessizce siler: cp1254 ile yazılıp UTF-8 olarak okunan Iğdır, Idr oldu.

"Latin-1 ile deneyin" öğüdü de aynı sorunu doğurur. ISO-8859-1, 256 bayt değerinin hepsini bir karaktere eşlediği için hiç hata vermez ve Türkçe metin sessizce Çankýrý olur.

UnicodeDecodeError: 'utf-8' codec can't decode byte

Dosya UTF-8 değildir ve mesajdaki bayt bir ipucudur. Türkçe veride 0xfd, 0xfe ya da 0xf0 cp1254'ü gösterir. 0xe9 (é) Batı Avrupa verisinde cp1252'ye işaret eder; 0xfc (ü) ise iki kod sayfasında da aynı harf olduğu için tek başına ikisini ayırmaz. pandas'ta kodlamayı parametre olarak verin: pd.read_csv("export.csv", sep=";", encoding="cp1254").

Windows'ta UnicodeEncodeError: 'charmap' codec can't encode character

Etkileşimli Windows konsolu Python 3.6'dan beri (PEP 528) UTF-8 yazar, ama bir dosyaya ya da pipe'a yönlendirilen çıktı ANSI kod sayfasını kullanır. Türkçe harfler cp1254'e sığar, ok işareti sığmaz: print("Istanbul → Ankara") içeren betik python script.py > out.txt ile çalıştırıldığında 'charmap' codec can't encode character '→' hatası verdi. Üç çözüm işe yaradı:

  • set PYTHONUTF8=1 (PowerShell'de $env:PYTHONUTF8=1) dosyalar ve standart akışlar için UTF-8 modunu açar.
  • python -X utf8 script.py aynısını tek bir çalıştırma için yapar.
  • PYTHONIOENCODING=utf-8 yalnızca standart akışları değiştirir, open() çağrısını değil.

UTF-8 modu, Python'un Windows rehberinde anlatılıyor. PEP 686 UTF-8 modunu Python 3.15'ten itibaren varsayılan yapıyor; 3.15'in kararlı sürümü 1 Ekim 2026 için planlanmış durumda. Her makine bu sürümü çalıştırana kadar kodunuzda encoding="utf-8" kalsın.

'latin-1' codec can't encode character biçimindeki hata genellikle bir HTTP header'ından gelir. Requests'in altta kullandığı http.client, header değerlerini Latin-1 ile kodlar; Iğdır değerini taşıyan bir header bu yüzden aynı hatayı verdi. Böyle değerleri yüzde kodlamasıyla (percent-encoding) gönderin ya da isteğin gövdesine koyun.

Bir web sayfasının kodlaması nereden gelir?

Tarayıcı bir sayfanın kodlamasına şu sırayla karar verir:

  1. Gövdenin başındaki bayt sırası işareti (BOM, byte order mark).
  2. Content-Type header'ının charset parametresi.
  3. MDN'ye göre ilk 1024 bayt içinde yer alması gereken <meta charset> etiketi.
  4. Baytlara bakılarak yapılan bir tahmin.

Requests yalnızca header'ı okur. Charset belirtilmemiş bir text/* türü için Requests dokümantasyonu RFC 2616'ya uyduğunu ve ISO-8859-1 kullandığını söylüyor; oysa RFC 7231 bu varsayılanı 2014'te kaldırdı. Charset'siz bir JSON yanıtı UTF-8 olarak okunur, diğer türler için tahmin yapılır. Düz text/html olarak sunulan test sayfalarımızda r.encoding her seferinde ISO-8859-1 çıktı. Bir sayfanın tarayıcıda doğru, betiğinizde yanlış görünmesinin sebebi bu.

windows-1254 ile ISO-8859-9 aynı mı?

Neredeyse. İkisi de Türkçe harfleri 0xA0 ile 0xFF arasında aynı baytlara koyar. 0x80 ile 0x9F arasında ise windows-1254'te , , ve bulunur, ISO-8859-9'da görünmeyen kontrol kodları vardır. WHATWG Encoding Standard tarayıcılara iso-8859-9 etiketini windows-1254, iso-8859-1 etiketini windows-1252 olarak okumalarını söyler; Python ise bunları ayrı codec'ler olarak ele alır. iso-8859-9 etiketli sayfamızda Beautiful Soup \x93Kampanya\x94 10\x80 üretti, from_encoding="cp1254" ile aynı baytlar “Kampanya” 10€ oldu. Böyle sayfaları cp1254 ya da cp1252 ile çözün.

Kendi HTML sayfanız charset'i nasıl bildirmeli?

Dosyayı UTF-8 olarak kaydedin, <head> bölümünün en başına <meta charset="utf-8"> koyun ve sunucunun Content-Type header'ının başka bir charset belirtmediğinden emin olun, çünkü header önceliklidir.

response.encoding, apparent_encoding mi, Beautiful Soup mu?

Her seçenek farklı bir sinyali okur:

  • r.encoding header'dan gelir. r.encoding = "cp1254" ayarlamak bilinen tek bir siteyi düzeltir; her site için "utf-8" ayarlamak ise windows-1254 kullanan siteleri bozar (test sayfamızda �ank�r�).
  • r.apparent_encoding, charset-normalizer'ın gövdeye bakarak yaptığı tahmindir. Türkçe sayfalarımızdan biri için Windows-1254, diğer ikisi için windows-1250 dedi; bu da ş harfini ţ yapar.
  • BeautifulSoup(r.content, "html.parser") <meta> etiketini kendisi okur. r.text değil, bayt verin; ayrıştırma tarafını BeautifulSoup Nedir ve Python'da Nasıl Kullanılır? yazımız anlatıyor.

Bizim sıramız tarayıcınınkini izler: önce BOM, sonra header'daki charset, ardından <meta> etiketi, en son tahmin. Hangisini kullandığınızı da log'a yazın. HTTPX farklı davranır: 0.28.1 sürümü header'da charset yoksa UTF-8 varsayar ve cp1254 sayfamız �ank�r� olarak geldi (HTTPX, Requests ve AIOHTTP Karşılaştırması).

Sayfaları tarayıcı gibi çözen bir Python scraper

Bu scraper (web sayfalarından veri toplayan betik) her URL'yi bir kez çeker, kodlamayı yukarıdaki sırayla seçer, ISO etiketlerini tarayıcıların yaptığı gibi eşler ve başlıkları Excel için bir CSV'ye yazar. Çalışması için pip install requests beautifulsoup4 yeterli. Yeniden deneme ya da IP döndürme yapmaz; bunlar için Scraping'de HTTP Hata Kodları ve Python'da Proxy'ler Nasıl Döndürülür? yazılarımıza bakın.

python
"""Sayfaları çeker, her birini bir tarayıcının yapacağı gibi çözer ve başlıkları Excel için bir CSV'ye kaydeder."""
import csv
import logging
import sys
from email.message import Message

import requests
from bs4 import BeautifulSoup
from bs4.dammit import EncodingDetector

PROXY = None  # örneğin "http://user:pass@pr.proxynet.io:8000"
USER_AGENT = "heading-reader/1.0 (+https://example.com/bot)"

# Tarayıcılar bu etiketleri Windows kod sayfaları olarak okur (WHATWG Encoding Standard); Python okumaz.
BROWSER_ALIASES = {
    "iso-8859-1": "cp1252", "iso8859-1": "cp1252", "latin1": "cp1252", "latin-1": "cp1252",
    "us-ascii": "cp1252", "ascii": "cp1252",
    "iso-8859-9": "cp1254", "iso8859-9": "cp1254", "latin5": "cp1254",
}

log = logging.getLogger("headings")


def header_charset(resp):
    """Content-Type header'ındaki charset ya da None. Requests'in kendi r.encoding
    değeri, charset'siz her text/* türü için burada ISO-8859-1 derdi."""
    msg = Message()
    msg["content-type"] = resp.headers.get("Content-Type", "")
    return msg.get_param("charset")


def pick_codec(resp):
    """(codec, geldiği yer) döndürür: önce BOM, sonra header, <meta charset>, en son tahmin."""
    bom = EncodingDetector.strip_byte_order_mark(resp.content)[1]
    if bom:
        return bom, "bom"
    declared = header_charset(resp)
    source = "header"
    if not declared:
        declared = EncodingDetector.find_declared_encoding(resp.content, is_html=True)
        source = "meta"
    if not declared:
        return resp.apparent_encoding or "utf-8", "guess"
    return BROWSER_ALIASES.get(declared.lower(), declared), source


def clean(text):
    """Bölünmez boşluk U+00A0 dahil, art arda gelen boşlukları teke indirir."""
    return " ".join(text.split())


def read_headings(session, url):
    resp = session.get(url, timeout=20)
    resp.raise_for_status()
    codec, source = pick_codec(resp)
    soup = BeautifulSoup(resp.content, "html.parser", from_encoding=codec)
    level = logging.WARNING if source == "guess" else logging.INFO
    log.log(level, "%s: %s from %s", url, codec, source)
    if soup.contains_replacement_characters:
        log.warning("%s: some bytes did not fit %s and became U+FFFD", url, codec)
    return [(url, codec, source, clean(h.get_text())) for h in soup.select("h1, h2")]


def main(urls, out="headings.csv"):
    session = requests.Session()
    session.headers["User-Agent"] = USER_AGENT
    if PROXY:
        session.proxies = {"http": PROXY, "https": PROXY}
    rows = []
    for url in urls:
        try:
            rows += read_headings(session, url)
        except requests.RequestException as exc:
            log.error("%s: %s", url, exc)
    # utf-8-sig önce bir BOM yazar, böylece Excel dosyayı UTF-8 olarak tanır
    with open(out, "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.writer(f)
        writer.writerow(["url", "codec", "source", "heading"])
        writer.writerows(rows)
    log.info("%d headings written to %s", len(rows), out)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, format="%(levelname)-7s %(message)s")
    main(sys.argv[1:] or ["https://example.com/"])

Betiği Python 3.13, Requests 2.34.2 ve Beautiful Soup 4.15.0 ile yerel bir HTTP proxy üzerinden çalıştırdık. Yerel test sayfaları, utf8hdr dışında, charset'siz text/html olarak sunuldu; son URL herkese açık bir sayfa:

text
INFO    http://127.0.0.1:8057/cp1254: windows-1254 from meta
INFO    http://127.0.0.1:8057/iso9: cp1254 from meta
INFO    http://127.0.0.1:8057/utf8meta: utf-8 from meta
INFO    http://127.0.0.1:8057/utf8hdr: utf-8 from header
INFO    http://127.0.0.1:8057/latin1: cp1252 from meta
WARNING http://127.0.0.1:8057/nometa: windows-1250 from guess
WARNING https://example.com/: ascii from guess
INFO    12 headings written to headings.csv

Header'da charset ya da <meta> etiketi olan her sayfa doğru çıktı; ISO-8859-1 etiketli sayfadaki “quoted” 5€ da buna dahil. İkisi de olmayan sayfa zayıf nokta: tahmin windows-1250 dedi ve CSV'ye Çankýrý ile ţubat yazıldı.

Aynı ülkedeki çok sayıda siteyi düzenli aralıklarla okuyorsanız, o ülkeden bir Residential Proxy yerel ziyaretçilerin gördüğü sayfaları getirir; kodlama mantığı aynı kalır.

"can't decode byte 0x8b" ve "0xa0" hataları ne anlama gelir?

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1

Bir gzip akışı 1F 8B ile başlar (RFC 1952); bu yüzden 1. konumdaki 0x8b, sıkıştırılmış verinin metin olarak çözüldüğünü gösterir. gzip.compress(...).decode("utf-8") bize tam olarak bu mesajı verdi. Scraping'de bu hata, r.raw verisini doğrudan okuduğunuzda ya da sıkıştırılmış yanıtı hiçbir zaman açmayan urllib.request ile kopyalanmış bir Accept-Encoding header'ı gönderdiğinizde çıkar. Requests gzip'i kendisi açar; kopyalanmış header'ı kaldırın ve r.content kullanın. urllib3'te isteğe bağlı Brotli ya da Zstandard paketi yüklü değilse kopyalanmış br ya da zstd değerleri de aynı sonuca götürür.

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0

cp1252, cp1254 ve ISO-8859-1'de bölünmez boşluk (U+00A0) tek bir A0 baytıdır; UTF-8'de ise hiçbir karakter bu baytla başlamaz. Dosyayı gerçek kodlamasıyla okuyun. Karakter zaten metninizdeyse "10\xa0kg".split() onu kaldırır, .split(" ") kaldırmaz; unicodedata.normalize("NFKC", s) ise onu düz bir boşluğa çevirir (NFKC, ² gibi karakterleri de 2 yapar).

Bozulmuş metin nasıl onarılır?

Hiçbir bayt kaybolmadıysa yanlış adımı tersine çevirin:

  • Ekrandan ya da bir hesap tablosundan kopyalanmış ışğ gibi bir metin: s.encode("cp1252").decode("utf-8") ışğ verir.
  • Aynı bozulma Requests'in r.text çıktısından geliyorsa içinde cp1252'nin kodlayamadığı bir kontrol karakteri (\x9f) saklıdır; bu durumda s.encode("latin-1").decode("utf-8") kullanın. cp1252 bu karakterde 'charmap' codec can't encode character '\x9f' hatasıyla durdu.
  • ISO-8859-1 olarak okunmuş windows-1254 metni, örneğin Çankýrý: s.encode("latin-1").decode("cp1254") Çankırı verir.

Büyük ya da karışık veride ftfy 6.3.1 UTF-8 kaynaklı mojibake'yi onarır: ftfy.fix_text("ışğ") ışğ döndürdü. Çankýrý metnine ise dokunmadı, çünkü bu geçerli bir Latin metni gibi görünür; kod sayfası karışıklıklarını elle düzeltin. Harflerin yerinde ? ya da olan metin onarılamaz; kaynağı yeniden çekin.

UTF-8 CSV dosyası Excel'de neden bozuk karakterlerle açılır?

Excel, çift tıklamayla açılan bir UTF-8 CSV'yi, dosya bir bayt sırası işaretiyle (BOM) başlıyorsa doğru gösterir; Microsoft'un destek sayfası da bunu belirtiyor. encoding="utf-8-sig" başa üç baytlık EF BB BF işaretini ekler; pandas'ta karşılığı df.to_csv("out.csv", encoding="utf-8-sig"). Bu dosyaları geri okurken de utf-8-sig kullanın: düz utf-8 ile csv modülü bize ilk sütun adı olarak şehir verdi, pandas ise BOM'u iki durumda da kaldırdı. Siteden Excel'e uzanan akışın tamamı Web Sitesinden Veri Çekme yazımızda.

"I".lower() neden "ı" döndürmez?

str.lower() Unicode'un dilden bağımsız varsayılan eşlemesini kullanır. Türkçe için bu iki yerde yanlış sonuç verir: "ISPARTA".lower() ısparta yerine isparta döndürür, "İ".lower() ise i harfiyle birlikte bir birleşik nokta (U+0307) döndürür. casefold() da aynı eksikliği taşır. Önce iki özel harfi eşleyin:

python
TR_LOWER = str.maketrans({"I": "ı", "İ": "i"})
TR_UPPER = str.maketrans({"i": "İ", "ı": "I"})

print("ISPARTA İZMİR".translate(TR_LOWER).lower())  # ısparta izmir
print("istanbul ışık".translate(TR_UPPER).upper())  # İSTANBUL IŞIK

Sayılar ve tarihler de yerel kurallara uyar. 1.299,90 gibi bir Türkçe fiyat, s.replace(".", "").replace(",", ".") ile float() fonksiyonunun okuyabileceği hâle gelir; pandas'ta da bunun için decimal="," ve thousands="." parametreleri var. Scraper'da locale.setlocale() kullanmaktan kaçının, çünkü bu çağrı bütün süreci etkiler. Fiyat temizlemenin tamamı E-Ticarette Rakip Fiyat Takibi Nasıl Yapılır? yazımızda.

Kullanım alanları

Sık yapılan hatalar

  • Hatayı errors="ignore" ya da latin-1 ile susturmak. Betik çalışır, harfler kaybolur ya da değişir.
  • Her site için r.encoding = "utf-8" yazmak. Bazı sayfaları düzeltir, windows-1254 kullananları bozar.
  • İki kez çözmek. Zaten doğru çözülmüş metne .encode().decode() uygulamak, sağlam metne yeni bir hata ekler.
  • iso-8859-9 ya da iso-8859-1 etiketini olduğu gibi kullanmak. Tarayıcılar windows-1254 ve windows-1252 kullanır; farkı tırnak işaretleri ve euro simgesi ortaya çıkarır.
  • utf-8-sig dosyasını utf-8 olarak okumak. İlk sütun adı görünmez bir karakterle başlar ve o sütunu adıyla arayan kod başarısız olur.
  • Karakter kodlamasını URL kodlamasıyla karıştırmak. Proxy şifresindeki %40 yüzde kodlamasıdır ve ayrı bir konudur (Node.js'te proxy şifresindeki özel karakterler).

Karar rehberi

İhtiyaçÖneri
Kendi .py dosyanızda ASCII dışı metinUTF-8 olarak kaydedin; coding satırına gerek yok
Dosya okuma ya da yazmaencoding="utf-8"; eski kod sayfası yalnızca onunla yazılmış dosyalar için
Windows'ta yönlendirilmiş çıktıda 'charmap' hatasıPYTHONUTF8=1 ya da python -X utf8; Python 3.15'ten itibaren varsayılan
Header'ında charset olmayan HTMLBeautiful Soup'a r.content verin, kodlamayı log'a yazın
Header'da charset yok, <meta> etiketi de yokSitenin kodlamasını sabitleyin; apparent_encoding son çare
Sayfa iso-8859-9 ya da iso-8859-1 diyorTarayıcı gibi cp1254 ya da cp1252 ile çözün
Metin zaten é ya da ı gibi görünüyor.encode("cp1252").decode("utf-8") ya da ftfy.fix_text
Sonuç Excel'de açılacakCSV'yi utf-8-sig ile yazın

Sıkça sorulan sorular

Python'da Türkçe karakterler için bir kütüphane gerekir mi?

Hayır. Python 3'te str Unicode'dur ve standart kütüphane yaygın kod sayfalarının codec'leriyle birlikte gelir (standart kodlamalar). Requests ile birlikte kurulan charset-normalizer bilinmeyen kodlamaları tahmin eder, ftfy ise mojibake'yi onarır.

cp1252 ya da cp1254 bir dosya UTF-8'e nasıl çevrilir?

Dosyayı eski kodlamasıyla okuyun, yenisiyle yazın: Path("new.txt").write_text(Path("old.txt").read_text(encoding="cp1254"), encoding="utf-8"). Path sınıfı pathlib modülünden gelir. Orijinali silmeden önce birkaç ismi kontrol edin.

errors="ignore" UnicodeDecodeError'ı çözer mi?

Hatayı gizler. Sığmayan baytlar uyarı verilmeden silinir ve isimler harf kaybeder. Bunun yerine doğru kodlamayı bulun.

Bir dosyanın hangi kodlamayı kullandığını nasıl anlarım?

BOM ile başlamıyorsa bir metin dosyası kendi kodlamasını kaydetmez, bu yüzden her araç tahmin yürütür. charset_normalizer.from_path("old.txt").best().encoding Türkçe test dosyamız için cp1254 döndürdü. Tahmini doğrulamak için dosyayı bu kodlamayla çözün ve Türkçe harf içeren birkaç sözcüğü okuyun.

utf-8 ile utf-8-sig arasındaki fark nedir?

utf-8-sig yazarken başa bir BOM (EF BB BF) ekler, okurken onu atlar. Excel'de açılacak CSV dosyaları için bunu kullanın.

pandas read_csv'de UnicodeDecodeError nasıl giderilir?

Dosyanın kodlamasını verin: Türkçe Windows çıktısı için encoding="cp1254", Batı Avrupa çıktısı için cp1252, dosyada BOM varsa utf-8-sig. encoding_errors="replace" hatayı durdurur ama harfleri kaybettirir.

Özet

Python'da Türkçe karakter sorunu tek bir kurala dayanır: baytları yazıldıkları kodlamayla çözün, kendi çıktınızı UTF-8 ile yazın. Hangi iki kodlamanın karıştığını bozuk metinden okuyun, her open() çağrısında encoding belirtin, Python 3.15 bunu sizin yerinize yapana kadar Windows'ta UTF-8 modunu kullanın ve web sayfalarını Beautiful Soup'a bayt olarak verin. Pek çok yerel siteden temiz metin toplaması gereken scraping işleri için veri kazıma çözümümüze göz atın.

ChatGPT'ye sorClaude'a sor