- 공유 링크 만들기
- X
- 이메일
- 기타 앱
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. 실전 트러블슈팅 체크리스트
- chardet으로 파일의 실제 인코딩 확인 → cp949, euc-kr, utf-16 등 감지
- open(), read_csv() 등 모든 파일 I/O에 encoding 명시 → 기본값 의존 금지
- Excel 호환이 필요하면 utf-8-sig 사용 → BOM 처리로 한글 깨짐 방지
- VSCode, 터미널, OS 인코딩을 utf-8로 통일 → 환경 간 불일치 제거
- Code Runner 사용 시 PYTHONIOENCODING=utf8 설정 → 출력 인코딩 문제 해결
- 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 완벽 해결 가이드 : 바로보기
댓글
댓글 쓰기