2012-06-13 10 views
5

私の背景はPerlですが、私はPythonとBeautifulSoupを新しいプロジェクトに使っています。Python、.format()、UTF-8

この例では、1つのページに含まれるリンクターゲットとリンクテキストを抽出して表示しようとしています。ここでは、ソースです:

table_row = u'<tr><td>{}</td><td>{}</td></tr>'.encode('utf-8') 
link_text = unicode(link.get_text()).encode('utf-8') 
link_target = link['href'].encode('utf-8') 
line_out = unicode(table_row.format(link_text, link_target)) 

.encodeするすべてのものを明示的に呼び出し(「UTF-8」)は、この作品を作るために私の試みですが、彼らは助けていないようだ - 私が完全だと考えられますPython 2.7がどのようにUnicode文字列を扱うのかを誤解しています。

とにかく。これはURLでU + 2013に出会うまでうまく動作します(本当にそうです)。その時点でアウトと、それは爆弾:

Traceback (most recent call last): 
File "./test2.py", line 30, in <module> 
    line_out = unicode(table_row.encode('utf-8').format(link_text, link_target.encode('utf-8'))) 
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 79: ordinal not in range(128) 

おそらく.format()、でも、Unicode文字列に適用される、愚かな-buggersを演奏し、.decode()操作をやろうとしています。そして、ASCIIがデフォルトであるので、それを使用しています。もちろん、U + 2013をASCII文字にマップすることはできません。

オプションは、それを削除するか、別のものに変換するようですしかし、私が欲しいのは単にそれを保存することだけです。最終的に(ちょっとしたテストケースです)、私はクリック可能なリンクを表示する必要があります。

BS3のドキュメントでは、デフォルトのエンコーディングをASCIIからUTF-8に変更することを提案していますが、同様の質問のコメントを読むことは、辞書を荒らしてしまうので本当に悪い考えです。

代わりにPython 3.2を使用するのは、このプロジェクトの一環として検討しているDjangoを使用していないということですが、この作業をきれいにする方法はありますか?それは1つですので、トレースバックからの一つです

line_out = unicode(table_row.encode('utf-8').format(link_text, link_target.encode('utf-8'))) 

line_out = unicode(table_row.format(link_text, link_target)) 

最初

VS:

+0

出力に(所望の符号化)の入力とエンコードに(ユニコードに)デコード、親指の基本的なルールとして:

ここですべてを説明し、私はPyConで与えたプレゼンテーションです。 – monkut

答えて

8

まず、あなたの2つのコードサンプルは、問題のある行のテキストに一致しないことに注意してください見る。最初のコードサンプルの残りの部分が正確であると仮定すると、ユニコード文字列を取得してエンコードしたため、table_rowはバイト列です。バイト文字列はエンコードできないので、Python 2は暗黙的にtable_rowをbyte-stringからunicodeにasciiとしてデコードして変換します。したがって、エラーメッセージ "UnicodeDecodeError from ascii"が表示されます。

どの文字列をバイト列にするのか、どの文字列をUnicode文字列にするのかを決定する必要があります。すべてのテキストを可能な限りUnicode文字列にしておくことをお勧めします。 Pragmatic Unicode, or, How Do I Stop The Pain?

+0

Aha。さて、ありがとう。それがこれを理解する初期の試みのように、私の固執している.encode()はどこでも、これがUnicode文字列からバイト文字列に変換されることを認識していなかったようです。 これらをすべて削除すると問題が解決したようです。 –

+0

また、一貫性のないコードスニペットにも問題があります。私はコードから関連する行をそのまま残し、同じ問題を抱えていた以前の実行のエラーを取り除いた。 –

+0

このプレゼンテーションはとても良いです!共有してくれてありがとう。 –