2018 업데이트 :
2018 년 2 월 현재와 같은 압축 사용 gzip
이 인기를 얻었습니다 (Google, YouTube, Yahoo, Wikipedia, Reddit, Stack Overflow 및 Stack Exchange Network 사이트와 같은 대규모 사이트를 포함한 모든 웹 사이트의 약 73 % 가 압축 사용).
응답이 gzipped 인 원래 답변과 같이 간단한 디코딩을 수행하면 다음과 유사한 오류가 발생합니다.
UnicodeDecodeError : 'utf8'코덱이 위치 1에서 바이트 0x8b를 디코딩 할 수 없습니다. 예기치 않은 코드 바이트
gzpipped 응답을 디코딩하려면 Python 3에서 다음 모듈을 추가해야합니다.
import gzip
import io
참고 : Python 2에서는 StringIO
대신 대신 사용 합니다.io
그런 다음 내용을 다음과 같이 파싱 할 수 있습니다.
response = urlopen("https://example.com/gzipped-ressource")
buffer = io.BytesIO(response.read()) # Use StringIO.StringIO(response.read()) in Python 2
gzipped_file = gzip.GzipFile(fileobj=buffer)
decoded = gzipped_file.read()
content = decoded.decode("utf-8") # Replace utf-8 with the source encoding of your requested resource
이 코드는 응답을 읽고 바이트를 버퍼에 배치합니다. gzip
모듈은 다음 판독하여 버퍼 GZipFile
기능. 그 후, zip으로 압축 된 파일을 다시 바이트 단위로 읽고 결국 읽을 수있는 텍스트로 디코딩 할 수 있습니다.
2010 년 원문 :
에 사용 된 실제 값을 얻을 수 있습니까 link
?
또한 .encode()
이미 인코딩 된 바이트 문자열을 시도 할 때 일반적으로이 문제가 발생 합니다. 따라서 다음과 같이 먼저 해독하려고 할 수 있습니다.
html = urllib.urlopen(link).read()
unicode_str = html.decode(<source encoding>)
encoded_str = unicode_str.encode("utf8")
예로서:
html = '\xa0'
encoded_str = html.encode("utf8")
실패
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
동안:
html = '\xa0'
decoded_str = html.decode("windows-1252")
encoded_str = decoded_str.encode("utf8")
오류없이 성공합니다. "windows-1252"는 제가 예제 로 사용한 것 입니다. 나는 chardet 에서 이것을 얻었고 그것이 옳다 는 0.5 자신감을 가지고있었습니다! (자, 1- 문자 길이 문자열로 주어진 것처럼, 당신은 무엇을 기대합니까?) 당신이 .urlopen().read()
검색 한 컨텐츠에 적용되는 것에서 리턴 된 바이트 문자열의 인코딩으로 변경해야 합니다.
내가 본 또 다른 문제는 .encode()
문자열 메서드가 수정 된 문자열을 반환하고 소스를 수정하지 않는다는 것입니다. 따라서 self.response.out.write(html)
html이 html.encode의 인코딩 된 문자열이 아니기 때문에 소용 이 없습니다 (원래 목표였던 경우).
Ignacio가 제안한 것처럼 소스 웹 페이지에서에서 반환 된 문자열의 실제 인코딩을 확인하십시오 read()
. 메타 태그 중 하나 또는 응답의 ContentType 헤더에 있습니다. 그런 다음의 매개 변수로 사용하십시오 .decode()
.
그러나 다른 개발자가 헤더 및 / 또는 메타 문자 집합 선언이 실제 내용과 일치하는지 확인할 책임이 있다고 가정해서는 안됩니다. (피타 어느, 그래, 내가 알아야 할, 나는 이었다 전에 그 중 하나).