5

私はBeautifulSoupを使用してWebサイトをスクレイプしています。ウェブサイトのページは私のブラウザでうまくレンダリングされます:

オックスファムインターナショナルのレポート「オフサイド! http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271

特に、一重引用符と二重引用符は問題ないように見えます。奇妙なことに、FF3でソースを表示すると、通常のASCIIであるように見えますが、ASCIIではなくhtmlシンボルに見えます。

残念ながら、私がこするとき、私はこのようなものを手に入れます

u'Oxfam International \xe2€™のレポート「\xe2€œOffside!」

おっと、私はこれを意味します:

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

ページのメタデータは、「iso-88959-1」エンコーディングを示しています。私はさまざまなエンコーディングを試し、unicode->asciiおよびhtml->asciiのサードパーティ関数で遊んで、MS / iso-8859-1の不一致を調べましたが、実際のところ、™は一重引用符で、unicode + htmlsymbolコンボを正しいASCIIまたはhtmlシンボルに変えることができないようです-私の限られた知識では、それが私が助けを求めている理由です。

アスキーの二重引用符「または」で満足します

次の問題は、他の面白いシンボルが正しくデコードされていないのではないかと心配していることです。

\xe2€™

以下は、私が見ているものを再現するためのPythonであり、その後に私が試したものが続きます。

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?q=htmlentitydefs&rnum=3&hl=en#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:

FF3.0.7とFirebugを搭載したMacOSX4を実行しています

Python 2.5(うわー、最初からこれを述べていなかったなんて信じられない)

4

2 に答える 2

8

これは、エンコーディングに関して、非常にめちゃくちゃなページの 1 つです :-)

あなたのアプローチにはまったく問題はありません。私はおそらく、それを 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
于 2009-03-10T13:15:41.757 に答える
4

実際には UTF-8 が CP1252 として誤ってエンコードされています。

>>> print u'Oxfam International\xe2€™s report entitled \xe2€œOffside!'.encode('cp1252').decode('utf8')
Oxfam International’s report entitled “Offside!
于 2009-03-10T13:21:42.193 に答える