2012-06-28 1 views
4

I URLLIB과 BeautifulSoup로 다음 코드가 있습니다URL 개방 인코딩

getSite = urllib.urlopen(pageName) # open current site 
getSitesoup = BeautifulSoup(getSite.read()) # reading the site content 
print getSitesoup.originalEncoding 
for value in getSitesoup.find_all('link'): # extract all <a> tags 
    defLinks.append(value.get('href')) 

그것의 결과 :

/usr/lib/python2.6/site-packages/bs4/dammit.py:231: UnicodeWarning: Some characters could not be decoded, and were replaced with REPLACEMENT CHARACTER. 
    "Some characters could not be decoded, and were " 

그리고 난이 사이트를 읽으려고 할 때 내가 얻을 :

�7�e����0*"I߷�G�H����F������9-������;��E�YÞBs���������㔶?�4i���)�����^W�����`w�Ke��%��*9�.'OQB���V��@�����]���(P��^��q�$�S5���tT*�Z 

답변

2

BeautifulSoup는 유니 코드와 함께 내부적으로 작동합니다. 기본적으로 UTF-8에서 비 유니 코드 응답을 시도하고 디코딩합니다.

로드하려고하는 사이트가 다른 인코딩을 사용하고있는 것처럼 보입니다. 예를 들어, UTF-16 대신 수 :

>>> print u"""�7�e����0*"I߷�G�H����F������9-������;��E�YÞBs���������㔶?�4i���)�����^W�����`w�Ke��%��*9�.'OQB���V��@�����]���(P��^��q�$�S5���tT*�Z""".encode('utf-8').decode('utf-16-le') 
뿯㞽뿯施뿯붿뿯붿⨰䤢럟뿯䞽뿯䢽뿯붿뿯붿붿뿯붿뿯붿뿯㦽붿뿯붿뿯붿뿯㮽뿯붿붿썙䊞붿뿯붿뿯붿뿯붿뿯붿铣㾶뿯㒽붿뿯붿붿뿯붿뿯붿坞뿯붿뿯붿뿯悽붿敋뿯붿붿뿯⪽붿✮兏붿뿯붿붿뿯䂽뿯붿뿯붿뿯嶽뿯붿뿯⢽붿뿯庽뿯붿붿붿㕓뿯붿뿯璽⩔뿯媽 

너무 mac_cyrillic가 될 수 :

>>> print u"""�7�e����0*"I߷�G�H����F������9-������;��E�YÞBs���������㔶?�4i���)�����^W�����`w�Ke��%��*9�.'OQB���V��@�����]���(P��^��q�$�S5���tT*�Z""".encode('utf-8').decode('mac_cyrillic') 
пњљ7пњљeпњљпњљпњљпњљ0*"IяЈпњљGпњљHпњљпњљпњљпњљFпњљпњљпњљпњљпњљпњљ9-пњљпњљпњљпњљпњљпњљ;пњљпњљEпњљY√ЮBsпњљпњљпњљпњљпњљпњљпњљпњљпњљгФґ?пњљ4iпњљпњљпњљ)пњљпњљпњљпњљпњљ^Wпњљпњљпњљпњљпњљ`wпњљKeпњљпњљ%пњљпњљ*9пњљ.'OQBпњљпњљпњљVпњљпњљ@пњљпњљпњљпњљпњљ]пњљпњљпњљ(Pпњљпњљ^пњљпњљqпњљ$пњљS5пњљпњљпњљtT*пњљZ 

하지만 난 당신로드하려고하는 사이트의 종류에 대해 너무 적은 정보를 가지고 인코딩 중 하나의 출력을 읽을 수도 없습니다. :-)

당신은 BeautifulSoup로 전달하기 전에 getSite()의 결과를 디코딩해야합니다 :

일반적으로
getSite = urllib.urlopen(pageName).decode('utf-16') 

하는 Content-Type의 형태로, 헤더에 사용 된 인코딩을 반환합니다 웹 사이트 헤더 (아마도 text/html; charset=utf-16 또는 유사).

+0

사이트는 = UTF-8 ", 또한 디코드 ("UTF-16 ")을 시도 나 복호화있어 문자셋했다 오류 – badc0re

+0

링크를 공유 할 수 있습니까? 사이트가 잘못 구성되어있을 수 있으므로 인코딩을 추측해야 할 수도 있습니다. –

+0

http://www.kafepauza.mk/ 여기 링크가 있습니다 – badc0re

2

페이지는 UTF-8에 있지만 서버는 압축 된 형식으로 당신에게 그것을 보내는 :

>>> print getSite.headers['content-encoding'] 
gzip 

당신은 아름다운 수프를 통해 실행하기 전에 데이터를 압축 해제해야합니다. 데이터에서 zlib.decompress()를 사용하는 중 오류가 발생했지만 파일에 데이터를 쓰고 gzip.open()을 사용하여 읽기에서 정상적으로 작동했습니다. 이유가 확실하지 않습니다.

1

동일한 문제가 발생했으며 Leonard가 언급 한 것처럼 압축 된 형식이 원인이었습니다.

This 링크가 요청 헤더에 ('Accept-Encoding', 'gzip,deflate')을 추가한다고 나와있는 문제를 해결했습니다. 예를 들면 : decode() 함수에 의해 정의된다

opener = urllib2.build_opener() 
opener.addheaders = [('Referer', referer), 
('User-Agent', uagent), 
('Accept-Encoding', 'gzip,deflate')] 
usock = opener.open(url) 
url = usock.geturl() 
data = decode(usock) 
usock.close() 
return data 

:

def decode (page): 
    encoding = page.info().get("Content-Encoding")  
    if encoding in ('gzip', 'x-gzip', 'deflate'): 
     content = page.read() 
     if encoding == 'deflate': 
      data = StringIO.StringIO(zlib.decompress(content)) 
     else: 
      data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(content)) 
     page = data.read() 

    return page 
+0

@MartijnPieters 경고를 보내 주셔서 감사합니다! 내 대답을 편집했습니다. – zanbri

+1

업데이트 해 주셔서 감사합니다. ! :-) –