• ベストアンサー

Python の utf16le デコードが化ける。

Python2.5で日本語を扱おうと試みています。 utf16le で書かれた "名" という文字を他の文字コードに変換しようとすると、なぜか"吊"に化けるという現象に悩んでいます。 他の文字ではこのような現象は見ていないのですが、何か使い方を間違っているのでしょうか? ちなみに、コンソールでは例えばna.txt の内容が "名"1文字として、 import codecs utf16_file = codecs.open('na.txt', 'r', 'utf_16_le') print utf16_file.readline() とすると"吊"が表示されてしまいます・・・。 どなたか原因に心当たりがあったら教えてください。m(_ _)m

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

動作環境はどういったものでしょうか? それと対話環境で実行した場合、どこかで(スタートアップ時のコンフィグファイルとか) エンコーディングを指定していないと Python 2.5.1 (r251:54863, May 18 2007, 16:56:43) [GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> import codecs >>> utf16_file = codecs.open('na.txt', 'r', 'utf_16_le') >>> print utf16_file.readline() Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character u'\u540d' in position 0 : ordinal not in range(128) >>> print utf16_file.readline(). File "<stdin>", line 1 print utf16_file.readline(). ^ SyntaxError: invalid syntax こんな風になると思うのですが。 で気がついたことが一つ。 >echo 吊名|nkf -S -w16|od -t x1 0000000 54 0a 54 0d 00 0d 00 0a 0000010 これはBigendianでの結果ですが、見ての通り'名'の 0x0aを 0x0dにすると'吊'です。 バイトストリームでCRLF変換ありで出力してたりしませんか?

finch_nk
質問者

お礼

どうもありがとうございます! ”バイトストリームをCRLF変換”がよく分からなかったのですが、色々調べてみた結果、どうやらそれが原因らしいことが分かりました。 (ほかにも文字コードの末尾?が0Dで終わる鰍やら倍が化けたのでそうだと思います。)  その線で解決できそうです!  どうもありがとうございました。

finch_nk
質問者

補足

早速ご回答ありがとうございます。 すみません。全くの初心者で ”バイトストリームでCRLF変換あり”という操作が分かりません・・・。 分かる限りでは、WindowsXP上でActivePython (2.5)を使っています。 設定の変更は、デフォルトのエンコードをsitecustomize.pyで cp932に指定したのみだと思います。 サンプルのファイルとして、"名"一文字にしましたが、実際には "紙に名前を書いた物が名刺である。"が "紙に吊前を書いた物が吊刺である。"となってしまいます・・・。

その他の回答 (3)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

わたしがWindowsで使っているのはPythonの配布元で配布しているものです。 ActivePythonを入れて試すというのはちょっとできないのでその辺は申し訳ないのですが、 sitecustmize.pyを import sys sys.setdefaultencoding('cp932') にして以下のように動作しています >python Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.getdefaultencoding() 'cp932' >>> def foo(): ... import codecs ... uf = codecs.open('na.txt', 'r', 'utf-16le') ... return uf.readlines() ... >>> foo() [u'\u540d\u523a\r\n'] >>> print foo()[0] 名刺 ファイルから読み込んできた状態でどうなっているか確認してもらえますか? とりあえず↑と同じ操作をやってもらえればOKです。

finch_nk
質問者

お礼

ご回答ありがとうございます。 結局ActivePythonのバージョンアップをしたら治ってしまいました・・・。 ただ、別環境では古いバージョンでも問題ないので、ActivePythonのせいではないはずです。やはり参考書などを見ながら何らかの設定をしてしまっていたのかも知れません。 どうもありがとうございました。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

ActivePythonは使ったことがないので微妙に違うかもしれませんが、 print utf16_file.readline() を print utf16_file.readline().encode('sjis') としたらどうなりますか? あるいは、 import sys import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) を実行してから試すと何か変化はありますか?

finch_nk
質問者

補足

ご回答ありがとうございます。 print utf16_file.readline().encode('sjis') としても、やはり"名"は化けました。 import sys import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) とすると、この段階で 16384 と表記され、その後は変化がありませんでした・・・。 ところで別のWindowsVistaのPCにActivePythonを入れて試したところ、 今度は問題なく動きました。 仕事で使っているのはXPの方なので、逆なら良かったのですが・・・。

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

Linux(Fedora8)のPython2.5.1だと問題なく処理できますね。 "名"が 540d で、"吊"が 540a なので、おそらく改行コードの問題でしょう。OSは何でしょうか?

finch_nk
質問者

お礼

どうもありがとうございました。 やはり改行コードの問題だったようです。 (ようです、というのは、ActivePythonのバージョンアップを兼ねて再インストールしたら治ってしまったのです・・・。多分、自分でなんか変な設定をして忘れていたのだと思います。お騒がせいたしました。) 改行コード?ということで、ほかの化ける文字を探していたら、似たような 文字コードのばかり(0Dで終わる)だったので、やはり改行コードを変換する過程でこれもいじっていたようです。  どうもありがとうございました。

finch_nk
質問者

補足

早速にご回答ありがとうございます。 WindowsXP上でActivePython (2.5)を使っています。 設定の変更は、デフォルトのエンコードをsitecustomize.pyで cp932に指定したのみだと思います。 文中でも化け、しかも他の文字には全く影響を与えません。 改行コードについて、いろいろ変えて試してみようと思います。 ありがとうございます。

関連するQ&A

  • Pythonで非日本語のUnicode文字が使えない

    日本Pythonユーザ会が配布している、Windows用のPython2.6.1を使用していますが、 日本語以外のUnicode文字、アクセントのあるフランス語やウムラウトのあるドイツ語を 「Unicode文字として」扱うと、強制終了してしまいます。 たとえば UTF-8 で保存した test.py   # encoding: utf-8   txt = u"日本語、にほんご、Japanese"   print txt   raw_input() は正しく実行・表示できますが、   # encoding: utf-8   txt = u"Français"   print txt   raw_input() とすると実行しても強制終了されてしまいます。 "u" を外すと "Franテァais" と表示してくれますが…。 どうすればフランス語の文字などを扱えるのでしょうか? Python初心者(1ヶ月程度)ですので、時間があれば、詳しく具体的に教えていただけると助かります。

  • PythonでUTF8の文字列をリストに入れると文字化けする

    PythonでUTF8の文字列をリストに入れると文字化けして、困っています。 以下、サンプルコードです。 a='あ' print a cmd=[] cmd.append(a) print cmd 結果は以下のようになります。 あ ['\xe3\x81\x82'] 文字化けしないようにリストに格納するにはどうすればよいでしょうか。 また、最終的にやりたいことは、リストの内容をLinuxのコンソールに出力することです。 Linux上で、$'\xe3'$'\x81'$'\x82'とすると'あ'という風に認識してくれるので、このようにリストに格納されれば良いと思っているのですが、良い方法はあるでしょうか。 よろしくお願いします。

  • MFCで、UTF-8で保存したい

    すいません。 またまた教えて下さい。 MFCで、UTF-8でファイルを保存しようとしていますが、うまくいきません。 下記のプログラムで、添付のエラーが出ます。 // UTF-8ファイル書き込み FILE* pFile1; fopen_s(&pFile1,"C:\\app\\8a.txt", "w, ccs=UTF-8"); //fopen_s(&pFile1,"C:\\app\\8a.txt", "w"); //UTF-8でないのでOK if (pFile1) { CStdioFile file(pFile1); file.WriteString(_T("abcあいうえお")); file.Close(); } <環境> windows8 visual studio2012(2008でも同じでした) MFCで、文字セットはマルチバイト文字セットを使用するにしています。 参考にしたHP http://faithandbrave.hateblo.jp/entry/20080724/1216890457 なぜでしょうか? よろしくお願い致します。

  • iframeでutf-8の.txtを呼び出す。

    HTMLのIframeで、文字コードがUTF-8であるテキストファイル(.txt)を呼び出す。(文字化け?) HTMLのIframeで、文字コードがUTF-8であるテキストファイル(.txt)を呼び出す時に、 内容が文字化けするので困っています。 表記に間違いがあるかもしれませんが、宜しくお願いします>< あと一応確認しましたが万が一既出でしたら申し訳ありません。 <iframe src=~>では、拡張子.htmlのファイルに加えて.txtファイルも呼び出せます。 .htmlファイルの場合、METAタグを使い、内側のHTML内で文字コードを指定しておけば 文字化けは起きないのですが、 txtファイルではそのような指定ができません。 外側(iframeを記述する方)から内側(src=~の呼び出し先)に向かって文字コードを 指定するのは可能ですか? 又はその他によい方法がありますか・・・?? 宜しくお願いしますm(_ _)m

    • ベストアンサー
    • HTML
  • 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) 例外処理をしない場合,デコード結果は「안녕」と読み込まれていました。 カタカナひらがな混じりのテキストを使う方に問題があるのかどうか分かりませんがせめて絵文字の場合だけでもテキストファイルへの正しく出力する方法をお教えください。

  • pythonでスクレイピングがうまく出来ません

    python2.7でbeautifulsoupを用いて、netkeiba.comから競馬情報(騎手の成績)をスクレイピングしています。 定法に基づきまして、『検証』からページのツリー構造を把握して、プログラムを作成しました。 馬名部分の構造が<td class="txt_l"> <a href="/horse/2011105901">テンテマリ</a></td> #テンテマリは馬名 となっておりましたので、"txt_l"を拾い出せるようにスクリプトを作りました。 しかしながら、 馬名以外の"txt_l"は全部スクレイピング出来るのですが、馬名部分だけがNoneと返ってまいります。 エラーメッセージではありませんが、何が原因でNoneとなるのかが、どうしても分かりません。 ちなみに、馬名以外で、ほぼ同様の構造を持つ、『レース名』、構造は <td class="bml txt_l"> <a href="/race/201603020812/" title="3歳上500万円下">3歳上500万円下</a> (3歳上500万円下はレース名) では、問題なくレース名を拾うことが出来ました。 該当のソースコード -*- coding:utf-8 -*- import urllib2 import codecs from bs4 import BeautifulSoup tpl_url='http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' for i in xrange( 1, 2 ): url=tpl_url.format( i ) soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml") tr_arr = soup.find('div', {'id':'contents_liquid'}).findAll('tbody') for tr in tr_arr: lrg1 = tr.findAll('td',{'class':'txt_l'}) for tr1 in lrg1: print tr1.string 試したこと 馬名以外の('td',{'class':'txt_l'})に準ずる『レース名』は、うまく拾うことが出来ました。 lrg1 = tr.findAll('td',{'class':'txt_l'}) で馬名を得ることが出来ない理由、併せて馬名を拾えるスクリプトを御教示くださいますよう、よろしくお願いいたします!

  • Python os.system 日本語ファイル名 文字化け

    python2.6 ubuntu 9.04 x64 ファイル文字コード UTF-8 # -*- coding: UTF-8 -*- import os, sys command = 'echo "あいうえお" > あああ.txt' os.system (command) このようにファイル出力すると、_____.txt と出力されます。 どのように解決するのでしょうか 直接 echo "あいうえお" > あああ.txt' とコマンドを打った場合は日本語ファイルが作成されます。 print sys.getfilesystemencoding() print sys.stdin.encoding print sys.stdout.encoding print sys.stderr.encoding print sys.getdefaultencoding() >UTF-8 >UTF-8 >UTF-8 >UTF-8 >ascii

  • UTF-8のテキストファイルを開く方法

    UTF-8のテキストファイルを開く方法 こんにちは。VBA初心者です。 FSOを使ってテキストファイルを開いてみたのですが、S-JISで開かれるらしく、文字化けしてしまいました。 そこで、WEBで調べてみると「ADODB.Stream」というものを使用すると、「オブジェクト.Charset = "UTF-8"」のように文字コードを指定できることがわかりました。 しかし、テキストストリームというものがいまいち理解できていないので使い方がよくわかりません。 以下のようなコードを書いてみましたが、「実行時エラー'438' オブジェクトは、このプロパティまたはメソッドをサポートしていません。」となってしまいました。 どこが間違っているのか教えていただけないでしょうか。 ちなみに「Open」ステートメント(Open バス名 For モード As #ファイル番号)を使用してテキストを内部的に開いた場合はどうなるのでしょうか。もし、標準でS-JISだった場合は、UTF-8にする方法はあるのでしょうか。 どうかよろしくお願いします。 Sub UTF8を開く() Dim myADODB As Object Set myADODB = CreateObject("ADODB.Stream") Dim i As Integer Worksheets("sheet1").Activate i = 1 With myADODB .Charset = "UTF-8" .ReadLine ("D:\test\sample.txt") Do Until .AtEndOfStream = True Cells(i, 1).Value = myADODB i = i + 1 Loop .Close End With End Sub

  • UTF-8 フラグ?で文字化けしました助けてください

    http://rev.go2.jp/MTAmazon.txt http://www.majordojo.com/projects/MTAmazon/downloads/ これなんですが 結論から言えば文字化けしてしまい困っています。 Movable Typeのplug-inなのですが構築すると上記のplug-inで出力した文字列のみが文字化けしないでその他の日本語文字列のみが化けます。 また、上記のplug-inで英数字のみの出力とした場合は正常に動作します。(文字化けしません) そして、設置するサーバーによって文字化けしなかったり、したりしています。Perlのバージョンの違うサーバーです。 どうやらPerlのせいと言うところまでは突き止めました。 そして、Perlの文字化け関連を漁っているとUTF-8フラグの存在が明らかになりました。 しかし、改造と言っても私に出来るのはコピペぐらいなので適当に先頭にuse utf8;とかplug-inのファイルをutf8エンドコードしてアップしてみたりuse encoding 'utf8';とか書いてみて全部文字化けしちゃったりして・・ でも手応えとしてはUTF-8フラグが問題なのかなという思いは強くしました。use encoding 'utf8';を追加する以外の改造は出力に変化はありませんでした。 # Perl のバージョン: 5.8.3 # Perl のバージョン: 5.8.7 サーバーは上記のPerlのバージョンで正常に動かしたいのです。 http://rev.go2.jp/は5.8.7の方のテスト環境です。出力した文字列以外が文字化けしている様が見られます。 http://rev.go2.jp/MTAmazon.txtはMTAmazon.plだけおいてみました。 よろしくお願いします

  • 各種スクリプト言語の記述時の文字コードについて

    掲題の通り、メジャーなLL言語についての文字コードについて質問です。 例えば PHPでコンソール用にちょっとしたものを書くとき #! /usr/local/php print("文字列"); 書いて、ターミナルで php ./sample.php などとすると問題なく「文字列」という文字が表示されます。 このとき、ファイルはUTF-8で書いたとします。 次に、別のLL言語pythonで下記の様に記述したとします。 #! /usr/local/python print ("python文字列"); 上記内容を python ./sample.py などと実行すると SyntaxError: Non-ASCII character '\xe6' in file と上記のようなエラーがでます。どうやらアスキーコードの範囲外のバイト数が含まれているようです。 これを #! /usr/local/python #coding: utf-8 print ("python文字列"); としてやると問題なく「python 文字列」と表示されると思います。 これはRubyでも同じだと思います。 また同じ様に #! /usr/bin/bash echo "文字列" とシェルスクリプトで上記の様にかいてやると・・・ 問題なく「文字列」と表記されます。 ではなぜシェルスクリプト(bash)やPHPはマジックコメントを記述しなくても 暗黙のうちにUTF-8で文字列が表記されて pythonやRubyは明示的にUTF-8とマジコメを記述しなければならないのでしょうか? ご教授ください。

    • ベストアンサー
    • PHP