1. ホーム
  2. python

[解決済み] Python エンコーディング utf-8

2022-03-02 20:46:11

質問

Pythonでいくつかのスクリプトを作成しています。ある文字列を作成し、それをファイルに保存しています。この文字列は、ディレクトリの樹状突起とファイル名から来る多くのデータを持っています。 convmvによると、私のすべての樹木はUTF-8である。

この後、MySQLに保存するので、すべてUTF-8のままにしておきたいのです。 今のところ、MySQLはUTF-8ですが、いくつかの文字(éやèなど - 私はフランス人です)で問題が発生しました。

Pythonが常にUTF-8の文字列を使用するようにしたいのです。インターネット上でいくつかの情報を読みましたが、私はこれが好きでした。

私のスクリプトはこれで始まります。

 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 def createIndex():
     import codecs
     toUtf8=codecs.getencoder('UTF8')
     #lot of operations & building indexSTR the string who matter
     findex=open('config/index/music_vibration_'+date+'.index','a')
     findex.write(codecs.BOM_UTF8)
     findex.write(toUtf8(indexSTR)) #this bugs!

そして、実行すると、以下のような答えが返ってきます。 UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2171: ordinal not in range(128)

編集してください。 なるほど、私のファイルでは、アクセントがきれいに書かれていますね。このファイルを作成した後、それを読み込んで、MySQLに書き込んでいます。 しかし、なぜか、エンコードの問題が発生しました。 私のMySQLデータベースはutf8で、SQLクエリのようです。 SHOW variables LIKE 'char%' は、utf8かバイナリしか返しません。

私の関数は次のようなものです。

#!/usr/bin/python
# -*- coding: utf-8 -*-

def saveIndex(index,date):
    import MySQLdb as mdb
    import codecs

    sql = mdb.connect('localhost','admin','*******','music_vibration')
    sql.charset="utf8"
    findex=open('config/index/'+index,'r')
    lines=findex.readlines()
    for line in lines:
        if line.find('#artiste') != -1:
            artiste=line.split('[:::]')
            artiste=artiste[1].replace('\n','')

            c=sql.cursor()
            c.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom="'+artiste+'"')
            nbr=c.fetchone()
            if nbr[0]==0:
                c=sql.cursor()
                iArt+=1
                c.execute('INSERT INTO artistes(nom,status,path) VALUES("'+artiste+'",99,"'+artiste+'/")'.encode('utf8')

そして、ファイルにきれいに表示されているアーティストが、BDDに悪い書き込みをします。 何が問題なのでしょうか?

解決方法は?

であるデータをエンコードする必要はありません。 すでに がエンコードされています。それをしようとすると、Pythonはまず最初に デコード に変更します。 unicode にエンコードする前に、UTF-8に戻してしまうのです。これが今回の失敗の原因です。

>>> data = u'\u00c3'            # Unicode data
>>> data = data.encode('utf8')  # encoded to UTF-8
>>> data
'\xc3\x83'
>>> data.encode('utf8')         # Try to *re*-encode it
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

データを直接ファイルに書き込むだけで、そこには いいえ は、すでにエンコードされたデータをエンコードする必要があります。

その代わりに unicode の値の代わりに、ファイルに書き込めるようにエンコードする必要があります。この場合 codecs.open() これは、unicode値をUTF-8にエンコードするファイルオブジェクトを返します。

また 本当に は、UTF-8 BOMを書き出したくありません。 ただし あなた ある を使用すると、UTF-8 を読み取ることができない Microsoft ツール (MS メモ帳など) をサポートすることができます。

MySQL のインサートの問題では、2 つのことを行う必要があります。

  • 追加 charset='utf8' を、あなたの MySQLdb.connect() を呼び出します。

  • 使用方法 unicode オブジェクトではなく str オブジェクトを使用します。 SQLパラメータを使用する で、MySQL コネクタが適切な処理を行えるようにします。

    artiste = artiste.decode('utf8')  # it is already UTF8, decode to unicode
    
    c.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom=%s', (artiste,))
    
    # ...
    
    c.execute('INSERT INTO artistes(nom,status,path) VALUES(%s, 99, %s)', (artiste, artiste + u'/'))
    
    

を使用すると、より効果的かもしれません。 codecs.open() を使い、内容を自動的にデコードします。

import codecs

sql = mdb.connect('localhost','admin','ugo&(-@F','music_vibration', charset='utf8')

with codecs.open('config/index/'+index, 'r', 'utf8') as findex:
    for line in findex:
        if u'#artiste' not in line:
            continue

        artiste=line.split(u'[:::]')[1].strip()

    cursor = sql.cursor()
    cursor.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom=%s', (artiste,))
    if not cursor.fetchone()[0]:
        cursor = sql.cursor()
        cursor.execute('INSERT INTO artistes(nom,status,path) VALUES(%s, 99, %s)', (artiste, artiste + u'/'))
        artists_inserted += 1

UnicodeとUTF-8とエンコーディングについてブラッシュアップしておくとよいでしょう。以下の記事をお勧めします。