• ベストアンサー

pythonのQRコードデコードで文字化け問題 2

前回の質問、「pythonのQRコードデコードで文字化けなくす 」でカタカナ混じりのテキストで文字化けが起きるた場合の回避策として例外処理の方法を教えてもらいその結果をテキストファイルの形で出力するため下記コードにしてみました。 import pyzbar.pyzbar from PIL import Image qr = pyzbar.pyzbar.decode(Image.open('d:/QRcode/qrcode_make.png')) #print(qr) try: with open('d:/QRcode/QRcode.txt', 'w') as f: print(qr[0].data.decode('utf-8').encode('shift-jis').decode('utf-8'), file=f) except UnicodeDecodeError: with open('d:/QRcode/QRcode.txt', 'w') as f: print(qr[0].data.decode('utf-8'), file=f) 前回の「いろはイロハ色波」「さけサケ鮭」のQRコード共に問題なくデコード結果が出力されました。 そこで頭に絵文字を加えた場合や韓国語・アラビア語等コピペしたテキストでQRコードを作りデコードした場合デコード結果が エラー(UnicodeEncodeError: 'cp932' codec can't encode character '\u231a' in position 0: illegal multibyte sequence)のためか出力されません。 因みに import qrcode text = 'text' img = qrcode.make(text) img.save('qrcode_make.png') でQRコードを生成 教えてもらったデコードの例外処理をする下記コードの結果 print(qr) try: print(qr[0].data.decode('utf-8').encode('shift-jis').decode('utf-8')) except UnicodeDecodeError: print(qr[0].data.decode('utf-8')) 元テキスト:⌚さけサケ鮭 デコード結果:⌚さけサケ鮭 元テキスト:안녕 デコード結果:エラー(UnicodeEncodeError: 'shift_jis' codec can't encode character '\uc548' in position 0: illegal multibyte sequence encoding with 'shift-jis' codec failed) 例外処理をしない場合,デコード結果は「안녕」と読み込まれていました。 カタカナひらがな混じりのテキストを使う方に問題があるのかどうか分かりませんがせめて絵文字の場合だけでもテキストファイルへの正しく出力する方法をお教えください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

エラーが起こっている部分を勘違いしていました。 printでファイルに書き込む段階でエラーになっているので、ファイルの文字コードを指定すればよさそうです。 with open('d:/QRcode/QRcode.txt', 'w', encoding='utf-8') as f: としたらどうでしょうか。

turu575
質問者

お礼

度々有り難うございます。お教え頂いた with open('QRcode.txt', 'w', encoding='utf-8') as f: print(decoded_str, file=f) でエラーなくデコードできました。 デコード結果:⏰さけサケ鮭 ソーステキスト:안녕 デコード結果:안녕 私もエラー内容で検索し、決定的な方法ではないがいけるみたいな記述があり もしかしたら「encoding=」は不要かと思い with open('QRcode.txt', 'w', 'utf-8') as f: 実行しましたが TypeError: 'str' object cannot be interpreted as an integer となり、私の方がはてなで状態で止まっていた状況です。 なお、今回使った下記コードの部分はそのままでもかまわないでしょうか retry_flg = False try: decoded_str = qr[0].data.decode('utf-8').encode('shift-jis').decode('utf-8') except UnicodeDecodeError: retry_flg = True except UnicodeEncodeError: retry_flg = True if retry_flg: decoded_str = qr[0].data.decode('utf-8')

その他の回答 (3)

回答No.4

TypeError: 'str' object cannot be interpreted as an integer こちらについて。 openの引数は、以下で確認できます。 https://docs.python.org/3.12/library/functions.html#open 引数名を省略すると、3番目の引数(buffering)として扱われるため、文字列だとエラーになります。

turu575
質問者

お礼

なるほど、'W'で省略されていたので何でも省略が可能だと思っていました。引数の内容まで確認せずコピペコードに始終していることに対し余計なお世話ばかりかけて申し訳ありません。 いろいろ有り難うございました。

回答No.3

except UnicodeEncodeError: retry_flg = True の部分はなくてもよさそうですが、残しておいても問題にはならないと思います。

turu575
質問者

お礼

有り難うございます。 そのままで行きます

回答No.1

UnicodeDecodeErrorだけを処理しているので、UnicodeEncodeErrorが起きた場合に対応できていないのが原因です。 exceptを2つ用意する方法と、基底クラスのUnicodeErrorをexceptで捕まえる方法がありますが、後者はUnicodeTranslateErrorも捕まえることになります(おそらく問題はないと思います) ただ、exceptの中でさらに例外が発生する可能性のある処理を行うことは推奨できません。 私なら、以下のようなコードにすると思います。ファイル操作も例外などの可能性があるので、デコード処理とは分離しています。 retry_flg = False try: decoded_str = qr[0].data.decode('utf-8').encode('shift-jis').decode('utf-8') except UnicodeDecodeError: retry_flg = True except UnicodeEncodeError: retry_flg = True if retry_flg: decoded_str = qr[0].data.decode('utf-8') with open('d:/QRcode/QRcode.txt', 'w') as f: print(decoded_str, file=f)

turu575
質問者

お礼

早速ありがとうございます。当方基本pytonに関わらずプログラミングは素人なので変なコードを書いていることお許しください。 下記のコードで試してみたところ import pyzbar.pyzbar from PIL import Image qr = pyzbar.pyzbar.decode(Image.open('qrcode_make.png')) #print(qr) retry_flg = False try: decoded_str = qr[0].data.decode('utf-8').encode('shift-jis').decode('utf-8') except UnicodeDecodeError: retry_flg = True except UnicodeEncodeError: retry_flg = True if retry_flg: decoded_str = qr[0].data.decode('utf-8') with open('QRcode.txt', 'w') as f: print(decoded_str, file=f) ソーステキスト:⏰さけサケ鮭 デコード結果:エラー エラー内容 Traceback (most recent call last): File "d:\Python\rqcode_4_3.py", line 15, in <module> print(decoded_str, file=f) UnicodeEncodeError: 'cp932' codec can't encode character '\u23f0' in position 0: illegal multibyte sequence となりました。なお絵文字をつけなければ問題なくデコードされます。単純にコピペだけでは問題があったのでしょうか

関連するQ&A