2017-12-10 4 views
3

Howdy 여러분,왜이 UTF-8 페이지를 디코딩 할 수 없습니까?

저는 파이썬을 사용하여 웹에서 데이터를 가져 오는 것이 처음입니다. 다음 코드 (예 : https://www.basketball-reference.com/boxscores/201712090ATL.html 같은) 다른 페이지를 위해 일했다 https://projects.fivethirtyeight.com/2018-nba-predictions/

: 나는 문자열이 페이지의 소스 코드를 가지고 싶습니다

import urllib.request 
file = urllib.request.urlopen(webAddress) 
data = file.read() 
file.close() 
dataString = data.decode(encoding='UTF-8') 

그리고 기대 HTML의 문자열로 dataString를 들어,

<!DOCTYPE html><html lang="en"><head><meta property="article:modified_time" etc etc 

대신 (이 특정한 경우에 내 기대 아래 참조) 538 웹 사이트,이 오류가 발생합니다 :

내 연구가 문제가 내 파일이 실제로 사용하여 인코딩되지 않는다는 것을 제안했다
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte 

UTF-8,하지만 두 페이지의 문자 세트와 아름다운 스프의 UnicodeDammit() 주장 그것은 UTF-8입니다 (두 번째는 첫 번째 이유 일 수 있습니다). chardet.detect()는 인코딩을 제안하지 않습니다.

라틴어-1

윈도우 1252

ISO-8859-1 : 나는 아무 소용에 'UTF-8'디코드의 인코딩 매개 변수()에 대해 다음을 대체 시도했습니다

아마도 언급할만한 가치가있는 것은 바이트 배열 데이터가 예상대로 보이지 않는다는 것입니다. 작업 URL에서 : [10] : 여기에 데이터의

b'\n<!DOCTYPE' 

여기에 데이터이다 [10] 538 사이트 :

b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03' 

가 무엇입니까?

+0

'wget'을 사용하여 데이터를 가져 오는 것은 압축되지 않은 gzip 압축 파일을 제공하여 일반 UTF-8 HTML 페이지를 제공합니다. 아마 서버가 잘못 구성되어 관련 헤더를 설정하지 않고 압축 된 페이지를 제공합니다. –

+0

('file.headers [ 'content-encoding']'을보십시오.) – Ryan

+0

@Ryan : 실제로'gzip'을'content-encoding'으로 설정하는 것처럼 보이지만'curl'이나'wget'도 그 일에 대해 아무것도하지 않습니다 이상하게 들리지만 일반적으로 트랜스 포트 레벨 압축을 투명하게 처리합니다 ...이 서버의 작동 방식이 이상해야합니다. –

답변

4

서버에서 gzip으로 압축 된 데이터를 제공했습니다. 일반적으로 urllibaccept-encoding 값을 설정하지 않으므로 서버는 보수적으로 데이터를 압축하지 않으므로 완전히 공통된 것은 아닙니다.

그래도, 당신이 당신의 페이지가 실제로 gzip으로 압축 된 것을 알 수있는 방법이 있으므로 응답 content-encoding 필드 세트는, 당신은 추가 처리하기 전에 파이썬 gzip 모듈을 사용하여 압축을 해제 할 수 있습니다. 당신은 압축을 포함하여 그 자체로이 모든 혼란을 처리 할 requests 모듈을 사용 할 수있을 경우

import urllib.request 
import gzip 
file = urllib.request.urlopen(webAddress) 
data = file.read() 
if file.headers['content-encoding'].lower() == 'gzip': 
    data = gzip.decompress(data) 
file.close() 
dataString = data.decode(encoding='UTF-8') 

OTOH은,에 (그리고 (난 당신이 또한 gzip 외에 deflate를 얻을 수있는 is the same but with different headers? 수 있음을 언급 않았다) 적어도 부분적으로) 인코딩.

import requests 
webAddress = "https://projects.fivethirtyeight.com/2018-nba-predictions/" 
r = requests.get(webAddress) 
print(repr(r.text)) 

이렇게하면 이미 복호화 된 유니 코드 문자열이 출력됩니다.

관련 문제