2013-11-25 10 views
16

私はUTF-8でエンコードされたWebページを取得するPythonプログラムを実行しています.HelloSoupを使用してHTMLからテキストを抽出します。UTF-8でエンコードされたHTMLをBeautifulSoupでUnicode文字列に正しく解析するには?

ただし、このテキストをファイルに書き込む(またはコンソールに出力する)と、予期しないエンコードで書き込まれます。

サンプルプログラム:

# u'Hier k\u0102\u015bnnen Sie sich kostenlos registrieren und/oder einloggen!' 

しかし、私は\xf6として単語könnenöをレンダリングするためにPythonのUnicode文字列を期待する:

# u'Hier k\xf6bnnen Sie sich kostenlos registrieren und/oder einloggen!' 
これは結果を与える実行

import urllib2 
from BeautifulSoup import BeautifulSoup 

# Fetch URL 
url = 'http://www.voxnow.de/' 
request = urllib2.Request(url) 
request.add_header('Accept-Encoding', 'utf-8') 

# Response has UTF-8 charset header, 
# and HTML body which is UTF-8 encoded 
response = urllib2.urlopen(request) 

# Parse with BeautifulSoup 
soup = BeautifulSoup(response) 

# Print title attribute of a <div> which uses umlauts (e.g. können) 
print repr(soup.find('div', id='navbutton_account')['title']) 

私は 'からEncoding 'パラメータをBeautifulSoupに設定し、read()decode()オブジェクトのresponseを試しても違いはありませんが、エラーが発生します。コマンドcurl www.voxnow.de | hexdump -C

、私は、Webページが実際にUTF-8でエンコードされた(すなわち、それは0xc3 0xb6が含まれています)ö文字のためであることがわかります。

 20 74 69 74 6c 65 3d 22 48 69 65 72 20 6b c3 b6 | title="Hier k..| 
     6e 6e 65 6e 20 53 69 65 20 73 69 63 68 20 6b 6f |nnen Sie sich ko| 
     73 74 65 6e 6c 6f 73 20 72 65 67 69 73 74 72 69 |stenlos registri| 

私はPythonの能力の限界を超えよ、私はこれをさらにデバッグする方法を失っています。何かアドバイス? utf-8に結果をエンコード

+0

奇妙な..として '\ u0102 \ u015b '' '' '' ''です。 – aIKid

+2

これはこの質問の複製ではありません:http://stackoverflow.com/questions/7219361/python-and-beautifulsoup-encoding-issues?rq=1 – justhalf

+0

@justhalf私はその質問を見ましたが、私は同じ結果を得たと思う。しかし、もう一度チェックします。ありがとう。 –

答えて

19

justhalfは、上記の指摘するように、ここでの私の質問は基本的にthis questionの複製です。

HTMLコンテンツは、UTF-8でエンコードされていると報告されています。ほとんどの場合、1つまたは2つの不正な無効なUTF-8文字を除きます。

soup = BeautifulSoup(response.read().decode('utf-8')) 

私はエラーを取得するでしょう:

これは明らかにエンコーディングが使用されている、と ようBeautifulSoupにこれをコンテンツを渡すときにUTF-8として第1デコードしようとしたときにどのBeautifulSoupを混乱させる

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 186812-186813: 
        invalid continuation byte 

出力をより詳しく見ると、誤って無効なバイトシーケンス0xe3 0x9cとしてエンコードされた文字Üのインスタンスではなく、正しいがありました。解析中のみ有効なデータがBeautifulSoupに渡されるように、現在highest-rated answerその質問のよう

は、無効なUTF-8文字は、削除することができ示唆している。

soup = BeautifulSoup(response.read().decode('utf-8', 'ignore')) 
3

は私のために働くようだ:

print (soup.find('div', id='navbutton_account')['title']).encode('utf-8') 

それが得られます。

Hier können Sie sich kostenlos registrieren und/oder einloggen! 
+0

Hmm ..私はいくつかのマシン(Python 2.7.3)で試しました。そのコードは 'ö '文字のために得ている2つの文字の代わりに4バイトを返します:' c4 82 c5 9b' –

関連する問題