Python爬虫基礎|文字列と符号化

4327 ワード

python文字列符号化の問題は,爬虫過程でファイルに出力してもDBデータベースに出力しても常に迂回できないような気がするので,今回出会った問題に乗じて学習記録を作成する.
Unicode Unicodeとはコンピュータがこの星の多くの言語をサポートできる暗号兵器です.Unicodeまでは、ASCIIが使われていました.ASCIIコードは非常に簡単で、英語の文字ごとに7ビットのバイナリ数でコンピュータに保存され、その範囲は32~126です.ユーザがファイルに大文字Aを入力すると、コンピュータはAのASCII符号値65をディスクに書き込み、コンピュータがファイルを読み出すと、まず65を文字Aに変換して画面に表示する.ASCIIコードのファイルは小さくて読みやすい.1つのプログラムは、ファイルのバイトごとに簡単に読み出し、対応する数字を文字に変換して表示するだけでよい.しかしASCIIの符号化には限界があり、後に8ビットのバイナリ方式で格納に拡張しても、何千もの文字を必要とする非ヨーロッパ語系の言語には少なすぎる.例えば、中国語を処理するには明らかに1バイトでは足りない.少なくとも2バイトが必要で、ASCIIの符号化と衝突することはできない.このようにして、中国はGB2312の符号化を制定した.世界には百種類以上の言語があり、日本はShift_JISに日本語を編成し、韓国はEuc-krに韓国語を編成し、各国には各国の基準があり、衝突は避けられない.その結果、多言語混在テキストには が表示されます.Unicodeはこの時点で誕生し、1つ以上のバイトを使用して1つの文字を表す方法によってASCIIの制限を突破した.このようなメカニズムの下で、Unicodeは90000文字を超えることを表すことができる.新しい問題はまた現れた:Unicode符号化に統一すれば、乱符号化問題はそれから消えた.しかし、あなたが書いたテキストが基本的にすべて英語であれば、Unicode符号化でASCII符号化よりも2倍の記憶空間が必要であり、記憶と伝送では非常にお得ではありません.そのため、節約の精神に基づいて、Unicode符号化を“ ”に変換するUTF-8符号化が現れた.UTF-8符号化Unicode文字を異なる数字の大きさに応じて1~6バイトに符号化し、よく使われる英語のアルファベットを1バイトに符号化し、漢字は通常3バイトで、辺鄙な文字だけが4~6バイトに符号化される.転送するテキストに英語の文字が大量に含まれている場合は、UTF-8で符号化するとスペースを節約できます.
現在のコンピュータシステムで通用する文字コードの働き方をまとめます.
コンピュータメモリではUnicode符号化を統一し、ハードディスクに保存する必要がある場合や転送する必要がある場合はUTF-8符号化に変換する.
PythonではUnicodeは中間符号と見なされ、異なる符号化間で変換する場合は、通常、文字列をdecodeに復号してUnicodeに符号化し、Unicodeから別の符号化に符号化する(encode).
  • decode:他の符号化文字列をUnicode符号化に変換する役割を果たす、例えばname.decode(“GB2312”)は、GB2312符号化文字列nameをUnicode符号化
  • に変換することを示す.
  • encode:Unicodeの符号化を他の符号化文字列に変換する役割は、例えば、name.encode(”GB2312“)Unicodeの符号化を示す文字列nameをGB2312の符号化
  • に変換することである.
    多くのPythonのソースファイルのヘッダには、次のような声明が表示されます.
    # coding:utf-8
    

    これは、宣言元コードのテキストがUTF-8であることを意味し、すなわち、Python解釈器にファイルのテキストをUTF-8で符号化された文字列と見なすように伝え、宣言された符号化はファイルの符号化と一致しなければならない.コードでは、ネットワークなどの他のソースのテキストを処理することが多いが、それらの符号化は必ずしもUTF-8ではないので、符号化変換を行う必要がある.
    Pythonはバイト列と文字列の間で気づかないように変換しようとした.異なる変換では、条件が許容される場合、Pythonは およびunicode文字列で直接変換しようとします.例えば、 unicodeバイトの列が一緒に接続されている場合.しかしencodingを用いずに異なるタイプ間で変換することは意味がない.したがってPythonは、sys.setdefaultencoding()によって指定されるデフォルトの符号化に依存する.ほとんどのプラットフォームでは、デフォルトはASCII符号化です.しかし、すべての変換について、この符号化を使用するのはほとんど間違っている.このデフォルト符号化は、手動で符号化を指定しない場合にstr()またはunicode()を呼び出すか、関数が文字列をパラメータとして呼び出されますが、他のタイプのパラメータが渡される場合に使用されます.これは、文字列オブジェクトが互いに変換されたときに文字符号化が指定されていないため、UnicodeEncodeError UnicodeDecodeErrorエラーが発生することが多いためです.
    例えば、unicodeおよびstrタイプに対して+により接合された場合、出力結果はunicodeタイプであり、strタイプの文字列をdecode()方法によりunicodeに復号してから接合することに相当する.この場合、復号時に符号化タイプが明確に指定されていない場合、エラーが発生する可能性があります.
    この問題を解決する1つの方法は、コードの先頭からsys.setdefaultencoding()を呼び出して、デフォルトの符号化を実際に使用される符号化に設定することである.しかし、これは問題を隠すだけで、最初はいくつかのテキスト処理の問題を解決することができますが.しかし、多くのアプリケーション、特にネットワークアプリケーションでは、異なる場所で異なるテキスト符号化が使用されるため、実際の実行可能性に欠けている.
    以下に、Pythonの文字コードを処理するためのいくつかのアドバイスを示します.
  • すべてのテキスト文字列は、unicodeタイプではなく、strタイプである必要があります.
  • バイト列を文字列に復号するには、var.decode(encoding)、例えばvar.decode(‘utf-8’)の正しい復号を使用する必要がある.テキスト文字列をバイトに符号化し、var.encode(encoding)を使用します.
  • は、unicode文字列に対してstr()を使用しないでください.また、符号化を指定せずにunicode()をバイト列に対して使用しないでください.
  • アプリケーションが外部からデータを読み出す場合、それをバイト列、すなわちstrタイプと見なし、.decode()を呼び出してテキストとして解釈する.同様に、テキストが外部に送信されると、常に.encode()がテキストに呼び出される.
  • が標準ストリームを操作する場合、環境変数PYTHONIOENCODINGの値を変更して標準ストリームのデフォルト符号化を設定することができ、sys.stdin.encodingおよびsys.stdout.encodingの値は所望の符号化である.

  • 参考資料
    廖雪峰の公式サイト-文字列とコードUnicode HOWTOhttp://www.tuicool.com/articles/2MVRVv7 https://gist.github.com/x7hub/178c87f323fbad57ff91 http://python.jobbole.com/86578/