質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

4477閲覧

PythonでXMLファイルの文字コード変換中にUnicodeDecodeErrorが出る

sera_sera

総合スコア16

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2018/10/17 06:00

前提・実現したいこと

卒業研究でPythonでアプリを作っているPython初心者です。
実現したいこととしまして、対象ディレクトリ(drive)下から拡張子xmlのファイルを全てUTF8に変換して選択したディレクトリに新規保存したいです。

発生している問題・エラーメッセージ

C:\Users\sera\PycharmProjects\PatentApp C:\Users\sera\PycharmProjects\save operation_start C:\Users\sera\PycharmProjects\PatentApp\translate\2013523997.xml C:\Users\sera\PycharmProjects\save\2013523997.xml Traceback (most recent call last): File "C:\Users\sera\PycharmProjects\PatentApp\patentApp\copyXMLfiles.py", line 37, in <module> for row in ff: # 元ファイルから1行ずつ読みだして File "C:\Program Files\Python37\lib\codecs.py", line 712, in __next__ return next(self.reader) File "C:\Program Files\Python37\lib\codecs.py", line 643, in __next__ line = self.readline() UnicodeDecodeError: 'euc_jp' codec can't decode byte 0xbf in position 2: illegal multibyte sequence [Finished in 0.221s]

該当のソースコード

Python3.7

1import sys # sysモジュール読み込み 2import glob # globモジュール読み込み 3import os # osモジュール読み込み 4import codecs # codecsモジュールの読み込み 5 6#sys.stdout = codecs.getwriter('utf_8')(sys.stdout) 7drive = r"C:\Users\sera\PycharmProjects\PatentApp" 8print(drive) # 確認用 9save = r"C:\Users\sera\PycharmProjects\save" 10print(save) # 確認用 11print("operation_start\n") 12 13os.chdir(drive) # カレントディレクトリを走査対象に移動 14path_list = glob.glob('**/*.xml', recursive=True) # 拡張子.xmlを網羅,リストに格納 15 16for x in path_list: # 拡張子.xml格納リストを網羅表示 17 fromdir = drive + '\' + x # 操作対象絶対パス 18 print(fromdir) # ↑の表示(確認用) 19 y = os.path.basename(fromdir) # 操作対象のファイル名取得 20 todir = save + '\' + y # 保存先ディレクトリの絶対パス 21 print(todir) # ↑の表示(確認用) 22 # ↓ 変換&新規出力 23 ff = codecs.open(fromdir, 'r', encoding='euc-jp') # 元ファイルを読み込み 24 fout_utf = open(todir, 'w', encoding='utf-8') # UTFでの新ファイルを新規作成 25 for row in ff: # 元ファイルから1行ずつ読みだして 26 fout_utf.write(row) # コピー先新ファイルに書き出す 27 ff.close() # ffを閉じる 28 fout_utf.close() # fout_utfを閉じる 29print("end")

試したこと

・#sys.stdout = codecs.getwriter('utf_8')(sys.stdout)の削除
・encoding='euc-jp'をencoding='utf-8'に書き換え

補足情報(FW/ツールのバージョンなど)

バージョン:Python3.7
開発環境:Atom1.31.2
こちらのサイトを参考にしました↓
https://www.python-izm.com/advanced/file_rw/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Python3.7を使っているのに、python2系のコードを参考にしているっぽいのはいかがなものでしょうか。

文字コードは、エラーから察するにBOM付きUTF-8ではないでしょうか。encoding='utf_8_sig'を試してみてください。

追記

Traceback (most recent call last): File "C:\Users\sera\PycharmProjects\PatentApp\patentApp\copyXMLfiles.py", line 37, in <module> for row in ff: # 元ファイルから1行ずつ読みだして File "C:\Program Files\Python37\lib\codecs.py", line 712, in __next__ return next(self.reader) File "C:\Program Files\Python37\lib\codecs.py", line 643, in __next__ line = self.readline() UnicodeDecodeError: 'euc_jp' codec can't decode byte 0xbf in position 2: illegal multibyte sequence [Finished in 0.221s]

なので、ff(読み込み側ファイル)が想定している文字コードと違うことは確実です。ヒントは「byte 0xbf in position 2」で、3バイト目(0から数えるから)に0xbfがあるということですから、BOMつきUTF-8のBOM「0xEF 0xBB 0xBF」を拾っている可能性が濃厚……ということです。

投稿2018/10/17 06:18

編集2018/10/17 07:14
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sera_sera

2018/10/17 07:05

ご回答ありがとうございます。 ご指摘通り、fout_utf = open(todir, 'w', encoding='utf-8_sig')に変えてみましたがエラーメッセージは変わりませんでした… ちなみに保存先であるsaveディレクトリには1つだけxmlファイルが生成されていて、何故か途中で文が途切れたxmlファイルでした。 ちなみに変換したいxmlファイルの一行目に<?xml version="1.0" encoding="EUC-JP"?>と書かれていたためeuc-jpで読み込んでいたのですがこれも間違っているのでしょうか?
hayataka2049

2018/10/17 07:07

説明が不十分でした。書き換えるのは ff = codecs.open(fromdir, 'r', encoding='euc-jp') の行です。出力ファイルのエンコーディングはutf-8のままでも構いません
hayataka2049

2018/10/17 07:09 編集

>ちなみに変換したいxmlファイルの一行目に<?xml version="1.0" encoding="EUC-JP"?>と書かれていたためeuc-jpで読み込んでいたのですがこれも間違っているのでしょうか? 実際問題としてeuc-jpを指定して読み込めていない以上、他のコードとみなして解決策を探るしかないんじゃないでしょうか。卒研ということは、過去の先輩が作ったデータということですか? それならどんな齟齬があってもおかしくない(悪くいう訳ではないが信頼はできない)ものですし
sera_sera

2018/10/17 07:17

ありがとうございます。 ご指摘のように(ご丁寧にありがとうございます)書き換えてみたところ、出力結果はそのままでエラーコードは … Traceback (most recent call last): File "C:\Users\T15015\PycharmProjects\PatentApp\patentApp\copyXMLfiles.py", line 37, in <module> for row in ff: # 元ファイルから1行ずつ読みだして File "C:\Program Files\Python37\lib\codecs.py", line 712, in __next__ return next(self.reader) File "C:\Program Files\Python37\lib\codecs.py", line 643, in __next__ line = self.readline() File "C:\Program Files\Python37\lib\codecs.py", line 556, in readline data = self.read(readsize, firstline=True) File "C:\Program Files\Python37\lib\codecs.py", line 502, in read newchars, decodedbytes = self.decode(data, self.errors) UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 0: invalid start byte になっていました。
sera_sera

2018/10/17 07:21

実情を少し話すと、公開特許公報というDVDからxmlファイルのみを抽出するというアプリなのですが、その過程でUTF-8に変換して欲しいと言われていましてこのコードを書いています。
sera_sera

2018/10/17 07:28

また新規生成されたはずの途中まで記述されているxmlファイルの中身なのですが、 <doc-number>2013523997</doc-number>という行以降が記述されていなくなっていました。ファイルの名前が2013523997.xmlと言うのですがファイル名前と同じ文字列が行に含まれていることが問題という可能性はありますでしょうか? 矢継ぎ早に申し訳ありません。
hayataka2049

2018/10/17 07:29

>ファイルの名前が2013523997.xmlと言うのですがファイル名前と同じ文字列が行に含まれていることが問題 はまずないと思います。
sera_sera

2018/10/17 07:57

nkf32を使ってみたところShift_JISと表示されました。 なのでff = codecs.open(fromdir, 'r', encoding='shift-jis')に書き換えて実行してみたところエラー無しで終了、新規生成されたxmlファイルを先ほどの方法で確認してみたところUTF-8になっていました!
hayataka2049

2018/10/17 08:00

sjisだったか。BOMっぽく見えたのはまぐれでしたね。しかし、<?xml version="1.0" encoding="EUC-JP"?>でSJISなのはなぜ・・・
sera_sera

2018/10/17 08:05

変換後のファイルの中身も確認してみましたが、やはり一行目はencoding='EUC-JP'?となっていましたね…。変換前も後も同じですがnkf32ではしっかりUTF-8となっているので大丈夫だとは思いますが…。
sera_sera

2018/10/17 08:07

とにかく解決本当にありがとうございました! これで研究を進める事ができますm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問