2 min read · 566 words
#538
이 글은 PowerShell에서 생성된 JSON 파일을 Python으로 로드할 때 'Unexpected UTF-8 BOM' 오류를 겪는 분을 위한 기록입니다. open() 함수의 인코딩 옵션 하나로 이 문제를 바로 해결합니다.
문제 상황
내가 PowerShell 스크립트에서 생성한 UTF-8 JSON 파일을 Python 스크립트에서 `json.load()` 함수를 이용해 읽어들이려고 시도했습니다. PowerShell의 `Out-File` 명령어가 기본적으로 UTF-8 BOM(Byte Order Mark)을 포함하여 파일을 저장한다는 사실을 간과한 것이 문제의 시작이었습니다. Python의 `json` 모듈은 기본 `encoding='utf-8'`으로 파일을 열 때 BOM을 처리하지 않아 오류가 발생했습니다.
에러 증상
파일을 로드하는 과정에서 다음과 같은 정확한 에러 메시지를 내가 겪었습니다.
`json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig)`
이 메시지는 JSON 파일의 첫 3바이트가 `\xef\xbb\xbf` (UTF-8 BOM)인데, 현재 사용 중인 디코딩 방식(`utf-8`)이 이를 예상하지 못하고 있다는 것을 명확히 알려주었습니다.
환경
나의 개발 환경은 다음과 같았습니다.
* **운영체제:** Windows 10 * **Python 버전:** Python 3.12 * **사용 모듈:** Python 표준 `json` 모듈 * **파일 생성 도구:** PowerShell 5.1 (기본 `Out-File` 명령 사용)
이러한 환경에서 PowerShell이 생성하는 파일의 인코딩 특성이 Python `json.load()`와 충돌하는 지점을 내가 발견했습니다.
시도했지만 실패한 방법
처음에는 JSON 파일의 첫 3바이트를 수동으로 제거하는 방법을 시도했습니다. 파일을 바이너리 모드로 읽어들인 후, 첫 3바이트를 슬라이싱하여 제거하고 `json.loads()`로 파싱하는 방식이었습니다.
`json.loads(raw_data[3:])`
하지만 이 방법은 다른 JSON 파일들, 즉 PowerShell이 아닌 다른 도구로 생성되어 BOM이 없는 파일들을 처리할 때 문제가 발생했습니다. BOM이 없는 파일에 대해 3바이트를 강제로 제거하면 파일 내용이 손상되어 `JSONDecodeError`가 계속 발생했습니다. 이 방법은 범용적이지 못하다는 것을 내가 깨달았습니다.
최종 해결
내가 찾은 최종 해결책은 Python의 `open()` 함수에 `encoding='utf-8-sig'` 옵션을 사용하는 것이었습니다. `utf-8-sig` 인코딩은 파일의 시작 부분에 UTF-8 BOM이 있을 경우 자동으로 이를 제거하고 내용을 디코딩합니다. 만약 BOM이 없다면 일반 `utf-8`처럼 동작하여 파일 내용을 정상적으로 읽어들입니다. 이 방법은 BOM의 유무에 관계없이 모든 UTF-8 JSON 파일을 안정적으로 처리할 수 있게 해주었습니다.
사용한 코드 또는 프롬프트
다음은 내가 문제를 해결하기 위해 사용한 코드입니다. 이전의 말썽난 코드와 수정 후의 코드를 비교하여 보여드립니다.
이전에는 `encoding` 옵션을 지정하지 않거나, 기본값인 `utf-8`을 사용했습니다. 이로 인해 BOM이 있는 파일에서 오류가 발생했습니다. 수정 후에는 `encoding='utf-8-sig'`를 명시하여 BOM 처리 문제를 해결했습니다.
# my_data.json (PowerShell이 생성한 JSON 파일)
# 이전 (말썽난 코드)
# import json
# with open("my_data.json", "r", encoding="utf-8") as f:
# data = json.load(f) # 여기서 JSONDecodeError 발생
# 수정 (바로잡은 후)
import json
path = "my_data.json"
with open(path, "r", encoding="utf-8-sig") as f:
data = json.load(f)
# 이제 data 변수에 JSON 내용이 정상적으로 로드됩니다.
검증 결과 및 현재 상태
내가 `encoding='utf-8-sig'`를 적용한 후, BOM이 포함된 JSON 파일과 BOM이 없는 일반 UTF-8 JSON 파일 모두를 대상으로 테스트를 진행했습니다. 모든 파일이 `json.load()` 함수를 통해 아무런 오류 없이 정상적으로 로드되는 것을 내가 확인했습니다. `JSONDecodeError`는 더 이상 발생하지 않았습니다. 현재 이 문제는 완벽하게 해결(fixed)된 상태입니다.
같은 문제 겪는 분들에게
만약 여러분도 Python에서 JSON 파일을 로드할 때 'Unexpected UTF-8 BOM' 오류를 겪고 있다면, 가장 먼저 `open()` 함수의 `encoding` 매개변수에 `utf-8-sig`를 지정해 보시길 내가 강력히 권합니다. 이 간단한 변경만으로 대부분의 BOM 관련 인코딩 문제를 해결할 수 있을 것입니다. 특히 PowerShell과 같은 도구로 생성된 파일을 다룰 때 유용한 팁입니다.