Python,chardet,cchardet을 사용하여 문자 인코딩 및 검사

14242 단어 python
만약 당신의 이름이 호세라면, 당신은 아주 좋은 회사입니다.하세는 매우 평범한 이름이다.그러나 텍스트 파일을 처리할 때, 때때로 José는 Josħħ, 또는 기타 손상된 기호와 자모 그룹으로 표시될 수 있다.또는, 어떤 경우, Python은 파일을 텍스트로 변환할 수 없으며 UnicodeDecodeError 으로 불만을 표시합니다.
디지털 데이터만 처리하지 않으면 모든 데이터 기사나 소프트웨어 개발자는 문자의 인코딩과 디코딩 문제에 직면해야 한다.

인코딩을 왜 합니까?


일찍이 이런 질문을 듣거나 물어본 적이 있다. "왜 우리는 문자 인코딩이 필요합니까?"사실상 문자 인코딩은 소프트웨어 개발자와 최종 사용자에게 대량의 곤혹을 가져다 줄 것이다.
하지만 생각해 보자. 우리는 모두 "문자 인코딩이 필요합니까?"라고 인정해야 한다.이 문제는 아무런 의의가 없다.만약 당신이 텍스트와 컴퓨터를 처리하고 있다면, 반드시 인코딩을 해야 합니다.예를 들어 알파벳'a'는 다른 어떤 것처럼, 하나의 바이트 (또는 여러 바이트) 로 기록되고 처리되어야 한다.가장 가능성이 있는 것은 텍스트 편집기나 터미널에서 "a"를 숫자 97로 인코딩하는 것입니다.인코딩이 없으면 텍스트와 문자열을 처리할 수 없습니다.바이트만 있습니다.

인코딩 및 디코딩


문자 인코딩을 일종의 극비 대체 암호로 상상하면 이런 암호에서 모든 자모는 인코딩할 때 대응하는 숫자가 있다.아무도 몰라요!
a: 61
g: 67
m: 6d
s: 73
y: 79
b: 62
h: 68
n: 6e
t: 74
z: 7a
c: 63
i: 69
o: 6f
u: 75
d: 64
j: 6a
p: 70
v: 76
e: 65
k: 6b
q: 71
w: 77
f: 66
l: 6c
r: 72
x: 78
위의 표로 인코딩하고 모든 내용을 숫자로 작성합니다.
print("\x73\x70\x61\x6d")
위의 4자 코드는 16진법입니다. 73, 70, 61, 6d(전의코드\x는 Python이 16진법 문자 코드를 지정하는 방식입니다.십진수는 115, 112, 97, 109이다.Python 콘솔이나 스크립트에서 상기 print 문장을 시도하면 우리가 좋아하는 스팸메일을 볼 수 있습니다.Python 콘솔에서 자동으로 디코딩되어 해당 문자(문자)를 인쇄합니다.
하지만 위의 숫자에 대한 바이트 문자열을 만들고 ASCII 인코딩을 지정합니다.
b"\x73\x70\x61\x6d".decode("ascii")
마찬가지로 "spam".만약 내가 들은 적이 있다면, 이것은 고정된 대답이다.
우리는 지금 인코딩과 디코딩을 하고 있습니다!여기 있습니다.

ASCII 이외의 복잡하고 아름다운 세계


그런데 우리 사랑하는 친구에게 무슨 일이 일어났을까?다시 말하면 알파벳'é'에 대응하는 숫자는 얼마나 됩니까?인코딩에 따라 달라집니다.누가 우리에게 말한 것처럼 숫자 233(16진법 e9)을 시험해 봅시다.
b"\x4a\x6f\x73\xe9".decode("ascii")

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)
그건 별로 좋지 않아요.이 오류는 233이 ASCII에서 사용하는 0-127 범위에 있지 않음을 나타냅니다.
괜찮아요.우리는 유니코드, 특히 UTF-8에 대해 들은 적이 있다.코드가 그들 모두를 지배한다!우리는 그것을 사용할 수 있다.
b"\x4a\x6f\x73\xe9".decode("utf-8")

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3: unexpected end of data
하지만 주사위는 없어요!대량의 실험을 거쳐 우리는 ISO-8859-1 인코딩을 찾았다.이것은 라틴어(즉 유럽에서 파생된) 문자 집합이지만, 이런 상황에서 유효하다. 왜냐하면 "José"의 자모는 모두 라틴어이기 때문이다.
b"\x4a\x6f\x73\xe9".decode("iso-8859-1")

'José'
우리 친구가 멀쩡히 돌아와서 매우 기쁘다.
만약 네가 라틴어만 할 줄 안다면, ISO-8859-1이면 된다.

그것은 허세가 아니다.이것은 또 다른 친구의 사진인데, 그가 라틴어를 한다.

UTF-8은 저희 친구입니다.


예전에는 모든 사람들이'미국어'라고 말했는데 문자 인코딩은 127자를 코드로 간단하게 번역한 다음에 다시 번역하는 것이다. ASCII 문자 인코딩은 그 중의 하위 집합을 보여 준다.물론 문제는 이런 상황이 실제로 존재한다면 당시 미국이 주도한 컴퓨터 업계의 결과이거나 간단한 단시(인종중심주의와 자만은 묘사성과 정확성을 더할 수 있고 우아하지 않다면)였다.현실은 훨씬 복잡하다.세상에는 각양각색의 사람과 언어가 있다.
다행히도 Unicode 이미 등장했고 문자 인코딩이 있어 세계 각지에서 사용되는 광범위한 문자를 대표할 수 있다."Miloš"및 "María"등의 비 Ascii 이름과张伟. 그 중 하나는 인코딩 UTF-8에서 흔히 볼 수 있는 것이다.이 페이지는 Python 버전 3 이후의 기본 인코딩입니다.
UTF-8을 사용하여 문자는 1, 2, 3 또는 4바이트로 인코딩할 수 있습니다.이것은 많은 배역을 포함하고 있다.♲, 水, 심지어😀. UTF-8은 ASCII와 호환되는 가변 너비입니다.다시 말하면, "a"는 여전히 바이트 수 97로 인코딩되어 있다.

문자 인코딩 검사


UTF-8은 없는 곳이 없지만 고유한 문자 인코딩은 아닙니다.하세가 위에서 분명히 발견한 것처럼.
예를 들어, 친애하는 Microsoft Excel은 일반적으로 CSV 파일을 라틴어 인코딩으로 저장합니다(업데이트된 버전이 있고 UTF-8 CSV를 명확하게 선택하지 않는 한).
우리가 뭘 써야 할지 어떻게 알아요?
가장 간단한 방법은 누군가가 결정을 내리고 명확한 소통을 하는 것이다.인코딩하는 사람이라면 가능한 한 적절한 Unicode 버전 UTF-8을 선택하십시오.그런 다음 UTF-8 디코딩을 항상 사용합니다.이것은 일반적으로 버전 3 이후 Python의 기본 설정입니다.icrosoft Excel에서 CSV 파일을 저장하려면 "CSV UTF-8"형식에서 "UTF-8-sig"문자 인코딩을 사용합니다 (메시지 또는 BOM 시작, 파일 시작에 UTF-8 문자를 지정하는 데 사용).더 전통적이고 고통스러운 Microsoft Excel CSV 형식을 사용한다면 문자 인코딩은 "cp1252"일 수 있습니다. 이것은 라틴 인코딩입니다.
몰라요?묻다
하지만 답이'나 몰라'라면 무슨 일이 일어날까?또는'우리는 문자 인코딩을 사용하지 않습니다'(🤦). 심지어 "아마 유니코드?"

이것들은 모두'나는 모른다'라고 해석되어야 한다

chardet, 유행하는Python 문자 검사 라이브러리


Python에서 처리해야 할 파일의 문자 인코딩이 무엇인지 모르는 경우 chardet 를 시도하십시오.
pip install chardet
위와 같은 도구를 사용하여 설치합니다.
chardet의 문자 검출 작업은 다음과 같습니다.
import chardet
name = b"\x4a\x6f\x73\xe9"
detection = chardet.detect(name)
print(detection)
encoding = detection["encoding"]
print(name.decode(encoding))
이것은 특히 name 변수에 ASCII가 아닌 문자가 많은 텍스트가 포함될 때 유효할 수 있습니다.이런 상황에서 내 기계에서 "José"와 함께 일하지만, 자신감이 없어서chardet은 다른 유사한 상황에서 실수를 할 수 있다.요약: 가능하다면 대량의 데이터를 주십시오.b'Jos\xe9 Gonz\xe1lez'라도 더 높은 정확성을 가져온다.print(detection) 의 답변 중 신뢰할 수 있는 수준을 보셨습니까?도움이 될 거예요.

문자 검출을 사용하는 두 가지 방법


라이브러리 chardet 를 사용할 수 있는 두 가지 방법이 있습니다.
우선, 나는 후속 약정에서 처음 사용하는 문자 인코딩을 확인하기 위해 텍스트 파일에 chardet.detect() 을 한 번에 사용할 수 있다.소스 시스템에서 항상 같은 문자 인코딩이 있는 CSV 파일을 내보낸다고 가정합니다.내가 도움말 핫라인에 연락했을 때, 그들은 심지어 문자 인코딩이 무엇인지 모르기 때문에, 나는 내가 자신의 장치에 의지할 수밖에 없다는 것을 선의로 나에게 알려주었다.다행히 내 장치는chardet이다.나는 큰 원본 파일에서 그것을 사용하고 인코딩을 cp1252 (이상하지 않음) 으로 확정한 후에 코드를 always with open("filename.csv", encoding="cp1252") as filehandle: 에 쓰고 나의 즐거움을 계속했다.나는 더 이상 캐릭터 검사를 필요로 하지 않는다.
두 번째 상황은 더욱 복잡하다.만약 내가 임의의 텍스트 파일을 처리하는 도구를 만들고 있다면, 문자 인코딩이 무엇인지 영원히 미리 알지 못할 것이다. 그러면 어떻게 해야 합니까?이런 상황에서 나는 항상 import chardet, 그리고 사용chardet.detect()을 원한다.그러나 신뢰도가 한도값보다 낮으면 오류나 경고를 던질 수 있습니다.자신이 있다면, 파일을 열고 읽을 때 제안된 인코딩을 사용할 것입니다.

cchardet, 미친 듯이 빠른 Python 문자 검출 라이브러리


위의 두 번째 장면에서 나는 성능이 향상되는 것을 감상할 수 있다. 특히 빈번하게 반복 조작하는 상황에서.
입력cchardet, 더 빠른chardet.이것은 대체품이다.
다음을 사용하여 설치합니다.
pip install cchardet
따라서 chardet과 호환되도록 가져옵니다.
import cchardet as chardet

간단한 명령행 도구


다음은 명령줄에서 파일 이름을 읽을 수 있는 사용cchardet의 전체 예입니다.
"""A tool for reading text files with an unknown encoding."""

from pathlib import Path
import sys

import cchardet as chardet


def read_confidently(filename):
    """Detect encoding and return decoded text, encoding, and confidence level."""
    filepath = Path(filename)

    # We must read as binary (bytes) because we don't yet know encoding
    blob = filepath.read_bytes()

    detection = chardet.detect(blob)
    encoding = detection["encoding"]
    confidence = detection["confidence"]
    text = blob.decode(encoding)

    return text, encoding, confidence


def main():
    """Command runner."""
    filename = sys.argv[1]  # assume first command line argument is filename
    text, encoding, confidence = read_confidently(filename)
    print(text)
    print(f"Encoding was detected as {encoding}.")
    if confidence < 0.6:
        print(f"Warning: confidence was only {confidence}!")
        print("Please double-check output for accuracy.")


if __name__ == "__main__":
    main()
당신도 할 수 있습니다 download this code from Github here.
상술한 내용을 텍스트 파일과 함께 적당한 디렉터리에 넣으십시오.그리고 터미널에서 이 디렉터리에서 다음과 같은 내용(필요한 경우 python이 아닌 python3을 사용할 수 있어야 합니다.
python3 somefile.csv
출력과 검출된 인코딩을 보셨습니까?
나는 모두가 아래의 평론을 발표하는 것을 환영한다.다른 용례, 문제에 부딪히거나 귀여운 돼지 그림을 추천해 주세요.
the associated Github repo 코드와 텍스트 파일의 예시를 보고 테스트하는 것을 환영합니다.다음과 같은 몇 가지 변경 사항은 시작 및 실행에 도움이 될 것입니다.
git clone https://github.com/bowmanjd/python-chardet-example.git
cd python-chardet-example/
python3 -m venv .venv
. .venv/bin/activate
pip install cchardet
python detect.py sample-latin1.csv
배역을 감상하다.

좋은 웹페이지 즐겨찾기