BeautifulSoup은 나에게 유니 코드를 똑바로 세우지 않고 유니 코드+HTML 기호를 제공합니다. 이것은 버그입니까 아니면 오해입니까?

StackOverflow https://stackoverflow.com/questions/629999

문제

나는 BeautifulSoup을 사용하여 웹 사이트를 긁어 모으고 있습니다. 웹 사이트의 페이지는 내 브라우저에서 잘 렌더링됩니다.

Oxfam International의 보고서는“오프사이드! http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271

특히, 단일 및 이중 인용문은 괜찮아 보입니다. 그들은 ASCII 대신 HTML 기호를 보이지만, FF3에서 소스를 볼 때 이상하게도 정상적인 ASCII 인 것으로 보입니다.

불행히도, 내가 긁을 때 나는 이런 것을 얻는다

u'oxfam International xe2 € ™의 보고서 xe2 € # offside!

죄송합니다.

u'Oxfam International\xe2€™s report entitled \xe2€œOffside!

페이지의 메타 데이터는 'ISO-88959-1'인코딩을 나타냅니다. 나는 다른 인코딩을 시도했고, 유니 코드-> ASCII 및 HTML-> ASCII 타사 기능으로 연주했으며 MS/ISO-8859-1 불일치를 살펴 보았지만 문제의 사실은 ™가 단일 인용문, 그리고 유니 코드+htmlsymbol 콤보를 제한된 지식으로 오른쪽 ASCII 또는 HTML 기호로 바꿀 수 없습니다. 그래서 제가 도움을 구하는 이유입니다.

나는 ASCII Double Quote, "또는"에 만족할 것입니다.

다음과 같은 문제는 내가 걱정된다는 것입니다. 다른 재미있는 기호가 잘못 해독되어 있다는 것입니다.

\xe2€™

아래는 내가보고있는 것을 재현 할 수있는 파이썬이며, 내가 시도한 것들이 뒤 따릅니다.

import twill
from twill import get_browser
from twill.commands import go

from BeautifulSoup import BeautifulSoup as BSoup

url = 'http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271'
twill.commands.go(url)
soup = BSoup(twill.commands.get_browser().get_html())
ps = soup.body("p")
p = ps[52]

>>> p         
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe2' in position 22: ordinal not in range(128)

>>> p.string
u'Oxfam International\xe2€™s report entitled \xe2€œOffside!<elided>\r\n'

http://groups.google.com/group/comp.lang.python/browse_frm/thread/9b7bb3f621b4b8e4/3b00a890cf3a5e46?

http://www.fourmilab.ch/webtools/demoroniser/

http://www.crummy.com/software/beautifulsoup/documentation.html

http://www.cs.tut.fi/~jkorpela/www/windows-chars.html

>>> AsciiDammit.asciiDammit(p.decode())
u'<p>Oxfam International\xe2€™s report entitled \xe2€œOffside!

>>> handle_html_entities(p.decode())
u'<p>Oxfam International\xe2\u20ac\u2122s report entitled \xe2\u20ac\u0153Offside! 

>>> unicodedata.normalize('NFKC', p.decode()).encode('ascii','ignore')
'<p>Oxfam International€™s report entitled €œOffside!

>>> htmlStripEscapes(p.string)
u'Oxfam International\xe2TMs report entitled \xe2Offside!

편집하다:

다른 BS 파서를 사용해 보았습니다.

import html5lib
bsoup_parser = html5lib.HTMLParser(tree=html5lib.treebuilders.getTreeBuilder("beautifulsoup"))
soup = bsoup_parser.parse(twill.commands.get_browser().get_html())
ps = soup.body("p")
ps[55].decode()

나에게 이것을 준다

u'<p>Oxfam International\xe2\u20ac\u2122s report entitled \xe2\u20ac\u0153Offside!

가장 좋은 사례 디코드는 나에게 동일한 결과를 제공하는 것 같습니다.

unicodedata.normalize('NFKC', p.decode()).encode('ascii','ignore')
'<p>Oxfam InternationalTMs report entitled Offside! 

편집 2 :

FF 3.0.7 및 FireBug로 Mac OS X 4를 실행 중입니다.

Python 2.5 (와우, 내가 처음부터 이것을 언급하지 않았다고 믿을 수 없다)

도움이 되었습니까?

해결책

그것은 심각하게 엉망인 페이지입니다.

당신의 접근 방식에는 전혀 잘못된 것이 없습니다. 나는 아마도 BeautifulSoup에 전달하기 전에 전환을하는 경향이있을 것입니다.

import urllib
html = urllib.urlopen('http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271').read()
h = html.decode('iso-8859-1')
soup = BeautifulSoup(h)

이 경우 페이지의 메타 태그가 인코딩에 대해 놓여 있습니다. 페이지는 실제로 UTF-8에 있습니다 ... Firefox의 페이지 정보는 실제 인코딩을 보여 주며 실제로 서버에서 반환 한 응답 헤더 에서이 숯을 볼 수 있습니다.

curl -i http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271
HTTP/1.1 200 OK
Connection: close
Date: Tue, 10 Mar 2009 13:14:29 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Set-Cookie: COMPANYID=271;path=/
Content-Language: en-US
Content-Type: text/html; charset=UTF-8

'UTF-8'을 사용하여 디코드를 수행하면, 그것은 당신에게 효과가 있습니다 (또는 적어도 나에게는).

import urllib
html = urllib.urlopen('http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271').read()
h = html.decode('utf-8')
soup = BeautifulSoup(h)
ps = soup.body("p")
p = ps[52]
print p

다른 팁

실제로 CP1252와 같이 UTF-8 잘못 모음입니다.

>>> print u'Oxfam International\xe2€™s report entitled \xe2€œOffside!'.encode('cp1252').decode('utf8')
Oxfam International’s report entitled “Offside!
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top