테이블을 내보냅니다. CSV를 엽니다. "José" 대신 "José"가 보입니다. "€" 대신 "€"가 보입니다. em-dash 대신 "â€""가 보입니다.
인코딩 지옥에 오신 것을 환영합니다.
이 가이드에서는 왜 이런 일이 발생하는지, 그리고 수동 내보내기든 추출 도구를 빌드하든 어떻게 해결하는지 설명합니다.
실제로 무슨 일이 일어나는가
문자 인코딩은 컴퓨터가 텍스트를 바이트로 표현하는 방식입니다. 서로 다른 인코딩은 같은 문자에 다른 바이트 패턴을 사용합니다.
가장 흔한 원인: UTF-8이 Latin-1로 해석됨 (또는 그 반대).
UTF-8은 비ASCII 문자에 여러 바이트를 사용합니다. 소프트웨어가 이 바이트를 Latin-1(단일 바이트 인코딩)으로 읽으면, 각 바이트가 별도의 깨진 문자가 됩니다.
| 문자 | UTF-8 바이트 | Latin-1으로 오독 시 |
|---|---|---|
| é | C3 A9 | é |
| € | E2 82 AC | € |
| — | E2 80 94 | â€" |
| ñ | C3 B1 | ñ |
패턴은 일관됩니다: 멀티바이트 시퀀스가 여러 개의 잘못된 문자가 됩니다.
인코딩이 깨지는 지점
1. 소스 페이지
웹사이트가 하나의 인코딩을 선언하지만 다른 것을 전송할 수 있습니다. 또는 아무것도 선언하지 않아 브라우저가 추측하게 만듭니다.
<!-- UTF-8 선언 -->
<meta charset="UTF-8">
<!-- 하지만 서버가 전송하는 것 -->
Content-Type: text/html; charset=ISO-8859-1
선언이 충돌하면 브라우저는 보통 알아냅니다. 내보내기 도구는 그렇지 않을 수 있습니다.
2. 내보내기 과정
추출 도구가 인코딩을 유지하지 않으면 바이트가 재해석됩니다.
JavaScript의 textContent는 유니코드 문자열을 반환하므로 안전합니다. 하지만 파일로 변환할 때 인코딩을 선택해야 합니다. 그 선택이 잘못되면 손상이 발생합니다.
3. 파일을 여는 애플리케이션
유효한 UTF-8 CSV를 내보냈습니다. Excel이 잘못 추측해서 Latin-1로 엽니다. 같은 손상, 다른 원인.
이것이 같은 파일이 한 애플리케이션에서는 정상이고 다른 곳에서는 깨지는 이유입니다.
문제 진단 방법
패턴 인식
특정 손상은 진단적입니다:
| 보이는 것 | 원래 문자 |
|---|---|
| á, é, Ã, ó, ú | á, é, í, ó, ú (스페인어 악센트) |
| ä, ö, ü | ä, ö, ü (독일어 움라우트) |
| ç | ç (세디유) |
| € | € (유로 기호) |
| â€" | — (em 대시) |
| ’ | ' (곡선 아포스트로피) |
à 뒤에 다른 문자가 보이면, UTF-8이 Latin-1로 읽힌 것입니다.
원시 바이트 확인
Python에서:
with open('file.csv', 'rb') as f:
print(f.read(100))
"é"가 예상되는 곳에 \xc3\xa9가 보이면 파일은 UTF-8입니다. \xe9가 보이면 Latin-1입니다.
페이지 선언 확인
브라우저 개발자 도구에서:
document.characterSet // 실제 사용된 인코딩 반환
손상된 파일 수정
재인코딩 트릭
UTF-8이 Latin-1으로 잘못 읽힌 경우, 되돌릴 수 있습니다:
# Latin-1로 읽기 (잘못 해석된 방식대로)
with open('corrupted.csv', 'r', encoding='latin-1') as f:
text = f.read()
# Latin-1 바이트로 다시 인코딩, 그다음 UTF-8로 디코딩
fixed = text.encode('latin-1').decode('utf-8')
with open('fixed.csv', 'w', encoding='utf-8') as f:
f.write(fixed)
이것은 손상이 단순한 오해석인 경우에만 작동합니다. 이중 손상이나 혼합 인코딩은 더 어렵습니다.
Excel에서 UTF-8로 읽기 강제
Excel은 종종 UTF-8을 무시합니다. 두 가지 해결책:
방법 1: BOM 추가
파일 시작 부분의 바이트 순서 표시가 UTF-8을 신호합니다:
with open('file.csv', 'w', encoding='utf-8-sig') as f:
f.write(data)
방법 2: 가져오기 마법사
CSV를 더블클릭하는 대신, 데이터 → 텍스트/CSV에서 가져오기를 사용하여 UTF-8 인코딩을 수동으로 지정합니다.
Google Sheets를 중간 단계로 사용
Google Sheets는 Excel보다 인코딩을 더 잘 처리합니다. CSV를 거기에 가져온 다음 XLSX로 내보냅니다. Excel 파일이 문자를 올바르게 유지합니다.
인코딩 문제 예방
수동 내보내기 시
인코딩을 올바르게 처리하는 도구를 사용하세요. HTML Table Exporter는 내보내기 과정 전체에서 유니코드를 유지하여, mojibake를 유발하는 변환 오류를 방지합니다.
CSV 내보내기 시 도구가 인코딩 옵션을 제공한다면, Excel 호환성을 위해 BOM 포함 UTF-8을 선택하세요.
추출 도구 구축 시
항상 인코딩을 명시적으로 지정하세요:
# CSV 쓰기
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerows(data)
# HTML 읽기
response = requests.get(url)
response.encoding = response.apparent_encoding # 자동 감지
html = response.text
JavaScript/브라우저 확장 프로그램의 경우:
// 명시적 인코딩이 포함된 Blob
const blob = new Blob(['\ufeff' + csvContent], {
type: 'text/csv;charset=utf-8;'
});
\ufeff는 Excel에 도움이 되는 BOM입니다.
Pandas 사용 시
# 읽기
df = pd.read_csv('file.csv', encoding='utf-8')
# Excel용 BOM 포함 쓰기
df.to_csv('output.csv', encoding='utf-8-sig', index=False)
문제를 일으키는 특수 문자
스마트 따옴표와 아포스트로피
워드 프로세서가 직선 따옴표를 곡선으로 변환합니다:
- ' → ' (U+2019)
- " → " " (U+201C, U+201D)
이것들은 UTF-8에서 멀티바이트이며 Latin-1에서 깨집니다.
Em 대시와 En 대시
- — (em 대시, U+2014)
- – (en 대시, U+2013)
금융 데이터와 출판물에서 흔합니다.
줄 바꿈 없는 공백
일반 공백은 0x20입니다. 줄 바꿈 없는 공백은 0xA0 (Latin-1) 또는 0xC2 0xA0 (UTF-8)입니다.
보이지 않지만 문자열 비교와 파싱을 깨뜨립니다.
# 공백 정규화
text = text.replace('\xa0', ' ')
통화 기호
€, £, ¥은 모두 ASCII 범위 밖이며 UTF-8 vs Latin-1에서 다르게 인코딩됩니다.
빠른 참조
| 문제 | 가능한 원인 | 해결 |
|---|---|---|
| Ã 뒤에 문자 | UTF-8이 Latin-1로 읽힘 | 재인코딩 또는 가져오기 시 UTF-8 지정 |
| ? 또는 □로 대체 | 인코딩이 해당 문자를 지원하지 않음 | 전 과정에서 UTF-8 사용 |
| Excel에서 깨진 문자 | Excel이 잘못된 인코딩을 추측 | UTF-8 BOM 사용 또는 가져오기 마법사 |
| 보이지 않는 문자가 데이터 깨뜨림 | 줄 바꿈 없는 공백 또는 제로 너비 문자 | 공백 정규화 |
근본 원칙
모든 단계에서 인코딩을 맞추세요. UTF-8로 내보내기. UTF-8로 열기. UTF-8로 저장.
한 단계에서라도 다른 인코딩을 사용하는 순간 문자가 손상됩니다.
확신이 없다면, BOM 포함 UTF-8이 Excel을 거칠 파일에 가장 안전한 선택입니다.
인코딩을 올바르게 처리하는 내보내기를 원하시나요? gauchogrid.com/ko/html-table-exporter에서 자세히 알아보거나 Chrome 웹 스토어에서 HTML Table Exporter를 무료로 사용해보세요.
Top comments (0)