バーニーが指摘するように、BS は内部で Unicode を使用しています。
の場合BS3
:
美しいスープは Unicode を提供します。
ドキュメントが解析されるまでに、ドキュメントは Unicode に変換されています。Beautiful Soup は、そのデータ構造に Unicode 文字列のみを格納します。
の場合BS4
、ドキュメントでは、これが発生した場合についてもう少し明確に説明しています。
文字列または開いているファイルハンドルを渡すことができます…まず、ドキュメントが Unicode に変換され、HTML エンティティが Unicode 文字に変換されます…`
つまり、データをすぐにデコードします。したがって、モジバケを取得している場合は、BS に移行した後ではなく、BS に移行する前に修正する必要があります。
コンストラクターへの入力は、BeautifulSoup
8 ビットのバイト文字列またはファイルを受け取り、エンコーディングを把握しようとします。詳細については、エンコーディングを参照してください。正しく推測できたかどうかは、印刷して確認できますsoup.original_encoding
。推測ISO-8859-1
または同義語ではない場合、唯一のオプションは明示的にすることです。decode
渡す前に文字列を指定し、ファイルを Unicode モードで開きますencoding
。
BS オブジェクトから出力される結果、およびメソッドに引数として渡すものはすべて、常に UTF-8 になります (バイト文字列の場合)。したがって、decode('iso-8859-1')
BS から取得したものを呼び出すと、まだ壊れていないものを壊すことが保証されます。
そして、あなたはとにかくこれをしたくありません。あなたがコメントで言ったように、「私はSQLite3データベースに出力しています。」さて、sqlite3 は常に UTF-8 を使用します。(pragma
実行時にこれを変更したり、コンパイル時にデフォルトを変更したりできますが、基本的に Python インターフェースを壊すので、…しないでください。)そして、Python インターフェースは Py2 str
(そしてもちろんPy2) で UTF-8 のみを許可します。 unicode
/Py3 str
、エンコーディングはありません。) したがって、BS データを Latin-1 にエンコードしてデータベースに保存しようとすると、問題が発生します。Unicode をそのまま保存するか、必要に応じて UTF-8 にエンコードします (Py2 のみ)。
このすべてを理解したくない場合は、 への最初の呼び出しの後にどこでも Unicode を使用すれば、BeautifulSoup
間違いはありません。