7

私のバックグラウンドは Perl ですが、新しいプロジェクトでは Python と BeautifulSoup を試してみます。

この例では、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 文字列に適用されたとしても、ばかげたことをして .decode() 操作を実行しようとしています。ASCII がデフォルトであるため、それを使用しています。もちろん、U+2013 を ASCII 文字にマップすることはできません。したがって...

オプションは、それを削除するか、別のものに変換することのようですが、実際に私が望むのは、単にそれを保持することです. 最終的に (これはほんの小さなテスト ケースです)、実際にクリックできるリンクを表示できるようにする必要があります。

BS3 のドキュメントでは、デフォルトのエンコーディングを ASCII から UTF-8 に変更することが提案されていますが、同様の質問に関するコメントを読むと、辞書が台無しになるため、非常に悪い考えのようです。

代わりに Python 3.2 を使用する以外に (つまり、このプロジェクトの一部として検討している Django を使用しないことを意味します)、これをきれいに機能させる方法はありますか?

4

1 に答える 1

11

まず、問題のある行のテキストが 2 つのコード サンプルで一致していないことに注意してください。

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))

最初のものはトレースバックからのものなので、それを見てください。table_rowUnicode 文字列を取得してエンコードしたため、最初のコード サンプルの残りの部分が正確であると仮定すると、バイト文字列になります。バイト文字列はエンコードできないため、Python 2 は、table_row を ascii としてデコードすることにより、バイト文字列から Unicode に暗黙的に変換します。したがって、エラー メッセージ "UnicodeDecodeError from ascii" が表示されます。

どの文字列をバイト文字列にするか、どれを Unicode 文字列にするかを決定し、それについて訓練する必要があります。すべてのテキストを可能な限り Unicode 文字列にすることをお勧めします。

PyCon で私が行ったプレゼンテーションで、すべてを説明しています: Pragmatic Unicode、または How Do I Stop The Pain?

于 2012-06-13T03:12:36.423 に答える