def read_file(path):
f = open(path, "r")
line = f.readline()
data = ""
while line:
data += line
line = f.readline()
f.close()
return data
smi 자막 파일을 열어서 싱크 조절을 위해 다음과 같이 코딩하고 즐거운 마음으로 실행을 하였습니다.
UnicodeDecodeError: 'cp949' codec can't decode byte 0x01 in position 1: illegal multibyte sequence
어김없이 등장하는 오류.. 인터넷에 검색해보니 수많은 예제가 뜨네요.
인코딩이 안 맞아서 안 열리나 봅니다. 파이썬은 기본적으로 파일이 ANSI로 작성되었다고 가정하고 cp949라는 코덱으로 파일을 엽니다.
open('파일경로', 'rt', encoding='UTF8')
'or'
open('파일경로', 'r', encoding='UTF8')
인터넷을 보니 이렇게 매개변수 옵션으로 UTF8을 주면 된다고 하네요
'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
뭐야.. 안되잖아 ??
확인해보니 파일 인코딩이 UTF-16입니다. UTF-16으로 바꿔서 열어보니 잘 열리네요.
인터넷에선 일반적으로 cp949로 안 열리면 utf8로 대부분 해결이 됐기 때문에 별다른 방법이 나와있진 않은 거 같네요.
파일 별로 인코딩이 다 다른경우가 있을 텐데 어떻게 해결할지 생각을 조금 해보았습니다.
try:
f = open(path, "r", 'utf-8')
lines = f.readlines()
except:
try:
f = open(path, "r", 'utf-16')
lines = f.readlines()
except:
print("Error")
처음에 생각한 방법은 예외처리를 이용하는 방법입니다.
try로 실행하고 예외 발생시 다른 인코딩으로 여는 방법입니다.
근데 이건 좀 문제인게 인코딩이 수십 가지가 넘을 건데 이렇게 쓰면 try except가 겹겹이 반복되어서 코드도 지저분하고 별로입니다. 도저히 마음에 드는 방법이 아니네요.
함수로 만들어서 재귀호출 하는 방법도 생각해봤는데 이것도 제 마음엔 들지 않았습니다.
혹시 파일을 열었을때 인코딩을 자동으로 인식하는 방법이 있지 않을까? 해서 찾아보니 관련 라이브러리를 찾았습니다.
소스코드
chardet이라는 모듈이 그 역할을 합니다.
pip install chardet
위 명령어를 통해 chardet을 미리 설치해주세요.
import os
import chardet
def read_file(path):
#파일 열어서 인코딩 확인
rawdata = open(path, 'rb').read()
result = chardet.detect(rawdata)
enc = result['encoding']
#인코딩 맞게 열기
f = open(path, "r", encoding = enc)
line = f.readline()
data = ""
while line:
data += line
line = f.readline()
f.close()
return data
위와 같이 일단 한번 읽어서 인코딩을 확인하고 그 인코딩 값을 open 함수에 넘겨서 한번 더 읽습니다.
두 번 읽는다는 점에선 효율성이 좀 떨어진다만 예외처리로 하는 방법보단 훨~씬 깔끔하고 편해서 공유합니다.
물론 chardet이 모든 인코딩을 인식하진 않으므로 특정 인코딩에선 못 읽을 수 있으나 웬만하면 다 된다고 보시면 됩니다. 아랍어 같은 거 쓰지 않는 이상요 ^^;;
그리고 chardet에서 반환한 인코딩 값이 open 함수에서 받는 encoding 매개변수랑 좀 다를 수 있습니다.
ex) chardet output : euc-kr -> open input : euckr :: not fit
아직까지 이런 문제는 확인을 못해봤으나 이런 문제가 발생한다면 따로 예외처리가 필요해보입니다.
=> 사용해보니 chardet 라이브러리가 어떤 라이브러리랑 인코딩 텍스트 호환이 안되면 호환이 안된다는걸 오류 메세지로 알려주기에 큰 문제가 없었습니다.
이제 어떤 파일을 읽던 잘 읽습니다. UTF8이던 , UTF16이던, ANSI이던..
그나저나 정규식 쓰는게 너무 어렵네요 ㅠ 특정 텍스트 위치부터 싱크 조절하는 프로그램이 필요한데 마땅하게 쓸만한 라이브러리도 없어서 직접만들고 있습니다
'프로그래밍 > Python' 카테고리의 다른 글
비트코인 픽 사이트와 연동해서 텔레그램 알림을 주는 프로그램을 개발했습니다 (0) | 2021.10.11 |
---|---|
[Python] smi 자막 특정 위치부터 싱크 조절하기 (0) | 2021.09.22 |
[Python] 가상화폐 트레이딩 봇 제작중 (0) | 2021.08.31 |
[Python] 이미지 URL 주소에서 확장자 추출하기 (0) | 2021.08.06 |
[Python] 문제 풀이 코드 저장용 (0) | 2021.05.08 |