Python UnicodeDecodeError utf-8 codec cant decode byte 완벽 해결 가이드

Python으로 CSV 파일을 읽거나 로그를 기록할 때 UnicodeDecodeError: 'utf-8' codec can't decode byte 에러를 만난 적이 있다면, 이 글이 당신의 시간을 절약해줄 것입니다. 이 문제는 파일의 실제 인코딩과 Python이 읽으려는 인코딩이 불일치할 때 발생하며, 특히 한글이 포함된 파일에서 빈번하게 나타납니다. 이 글에서는 원인 진단부터 환경별 해결 코드까지 실전에서 바로 적용 가능한 솔루션을 제시합니다.


Python UnicodeDecodeError utf-8 codec cant decode byte 완벽 해결 가이드




1. 에러 발생 원인과 진단

UnicodeDecodeError는 파일 저장 시 사용된 인코딩과 읽기 시 지정한 인코딩이 다를 때 발생합니다. 주요 원인은 다음과 같습니다.

  • Windows 환경의 기본 인코딩(cp949/euc-kr)과 Python 기본값(utf-8) 불일치
  • Excel에서 저장한 CSV 파일의 인코딩이 utf-8이 아닌 경우
  • VSCode, 터미널, OS 간 인코딩 설정 차이
  • BOM(Byte Order Mark)이 포함된 utf-8 파일을 일반 utf-8로 읽을 때

문제를 해결하기 전에 파일의 실제 인코딩을 확인하는 것이 가장 중요합니다. chardet 라이브러리를 사용하면 정확한 인코딩을 감지할 수 있습니다.

pip install chardet

import chardet

with open('example.txt', 'rb') as f:
    data = f.read()
    result = chardet.detect(data)
    print(result)  # {'encoding': 'cp949', 'confidence': 0.99, ...}

감지된 인코딩이 cp949라면, 해당 인코딩으로 파일을 읽어야 합니다.

2. 파일 입출력 시 인코딩 명시 (핵심 해결법)

Python에서 파일을 다룰 때는 반드시 encoding 파라미터를 명시해야 합니다. 기본값에 의존하면 환경에 따라 동작이 달라집니다.

일반 파일 읽기/쓰기

# cp949로 저장된 파일 읽기
with open('old_file.txt', 'r', encoding='cp949') as f:
    data = f.read()

# utf-8로 새로 저장
with open('new_file.txt', 'w', encoding='utf-8') as f:
    f.write(data)

pandas CSV 처리

pandas의 read_csv와 to_csv에서도 인코딩을 명시해야 합니다. 특히 Excel과 호환이 필요한 경우 utf-8-sig를 사용하는 것이 핵심입니다.

import pandas as pd

# cp949로 인코딩된 CSV 읽기
df = pd.read_csv('data.csv', encoding='cp949')

# Excel 호환 CSV 저장 (BOM 포함)
df.to_csv('output.csv', encoding='utf-8-sig', index=False)

utf-8-sig를 사용하는 이유: Excel은 BOM(Byte Order Mark)이 없는 utf-8 파일을 제대로 인식하지 못해 한글이 깨집니다. utf-8-sig는 파일 앞에 BOM(EF BB BF)을 추가하여 Excel이 utf-8임을 인식하게 합니다. 또한 CSV를 읽을 때 BOM 문자가 첫 번째 필드에 포함되는 문제도 방지합니다.

logging 모듈

import logging

file_handler = logging.FileHandler('app.log', encoding='utf-8')
file_handler.setLevel(logging.INFO)

logger = logging.getLogger()
logger.addHandler(file_handler)
logger.info('한글 로그 테스트')

3. 개발 환경별 인코딩 설정

코드뿐만 아니라 에디터, 터미널, OS의 인코딩을 utf-8로 통일하는 것이 근본적인 해결책입니다.

VSCode 설정

settings.json에 다음을 추가합니다.

{
  "files.encoding": "utf8",
  "files.autoGuessEncoding": false,
  "[python]": {
    "editor.defaultFormatter": "ms-python.python"
  }
}

Code Runner 확장을 사용한다면 Executor Map 설정을 수정해야 합니다.

"code-runner.executorMap": {
  "python": "set PYTHONIOENCODING=utf8 && python -u"
}

이 설정은 Python 실행 시 표준 입출력의 인코딩을 utf-8로 강제합니다. -u 옵션은 버퍼링을 비활성화하여 출력이 즉시 표시되도록 합니다.

Windows CMD/PowerShell

# CMD에서 UTF-8로 전환 (코드 페이지 변경)
chcp 65001

# PowerShell에서 UTF-8 설정
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

매번 입력하기 번거롭다면 시스템 환경 변수 PYTHONIOENCODING을 utf-8로 설정하는 것을 권장합니다.

Google Colab matplotlib 한글 폰트

!apt-get install -y fonts-nanum
!rm -rf /root/.cache/matplotlib/

import matplotlib as mpl
import matplotlib.pyplot as plt

path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf'
font_name = mpl.font_manager.FontProperties(fname=path).get_name()
plt.rcParams['font.family'] = font_name
plt.rcParams['axes.unicode_minus'] = False  # 마이너스 기호 깨짐 방지

설정 후 런타임을 재시작해야 폰트가 적용됩니다.

4. MySQL/DB 로드 시 인코딩 처리

LOAD DATA INFILE로 CSV를 MySQL에 적재할 때도 인코딩 문제가 발생합니다. 특히 백슬래시(\)나 구분자가 데이터에 포함된 경우 주의가 필요합니다.

LOAD DATA INFILE '/path/to/file.csv'
INTO TABLE db.table_name
CHARACTER SET latin1
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
ESCAPED BY ''
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
  • CHARACTER SET latin1: utf-8로 해결되지 않을 때 시도할 대안
  • ESCAPED BY '': 백슬래시 때문에 열 수가 맞지 않을 때 이스케이프 문자를 비활성화
  • ENCLOSED BY: 데이터에 구분자가 포함되어 있으면 인용 문자로 감싸기

DB 테이블의 컬럼 인코딩도 utf8mb4로 설정되어 있는지 확인해야 합니다.

5. 실전 트러블슈팅 체크리스트

  1. chardet으로 파일의 실제 인코딩 확인 → cp949, euc-kr, utf-16 등 감지
  2. open(), read_csv() 등 모든 파일 I/O에 encoding 명시 → 기본값 의존 금지
  3. Excel 호환이 필요하면 utf-8-sig 사용 → BOM 처리로 한글 깨짐 방지
  4. VSCode, 터미널, OS 인코딩을 utf-8로 통일 → 환경 간 불일치 제거
  5. Code Runner 사용 시 PYTHONIOENCODING=utf8 설정 → 출력 인코딩 문제 해결
  6. DB 적재 시 CHARACTER SET, ESCAPED BY 옵션 조정 → 구분자/이스케이프 문제 처리

파일 타입별 권장 인코딩 요약:

  • .py 소스 코드: utf-8 (PEP 8 권장)
  • .txt, .log: utf-8 (범용성)
  • .csv (Excel용): utf-8-sig (BOM 포함)
  • .json, .html: utf-8 (웹 표준)

정리 및 Action Item

UnicodeDecodeError는 인코딩 불일치 문제이므로, 파일의 실제 인코딩을 확인한 뒤 읽기/쓰기 시 동일한 인코딩을 명시하면 해결됩니다. 모든 환경을 utf-8로 통일하고, Excel 호환이 필요한 CSV는 utf-8-sig를 사용하는 것이 핵심입니다. 지금 당장 실행할 수 있는 액션은 chardet을 설치하고 문제가 되는 파일의 인코딩을 확인한 뒤, 해당 인코딩으로 파일을 읽어 utf-8로 재저장하는 것입니다. 이 과정만으로도 대부분의 인코딩 문제는 해결됩니다.


#함께 읽으면 좋은 글

Python Requests SSL 인증서 오류 CERTIFICATE_VERIFY_FAILED 완벽 해결 가이드 : 바로보기

댓글