前提
pythonで配列に格納したフレーズをテキストファイル内から抽出し、その前後の行と合わせて新たなテキストに保存するというプログラムを作成しているのですが、間違いがないようにchardetを用いて文字コードを調べてから開いているのにも関わらず、readlines()関数を実行しようとするとデコードエラーが表示されてしまい先に進めません。
実現したいこと
- readlines()関数でデコードエラーを起こさず、その後の処理に渡せるようにすること。
発生している問題・エラーメッセージ
UnicodeDecodeError: 'cp932' codec can't decode byte 0xe1 in position 7: illegal multibyte sequence
該当のソースコード
python
1import os 2import sys 3from chardet import detect 4 5results = open('output.txt', 'a', encoding='UTF-8') # 検索・抽出した行を入力するためのテキストファイル 6 7errorlist = ['Showing results for', 'Consider adding a lang attribute to ', 'Element title must not be empty', 'seen when expecting text or an end tag.', 'Unclosed element ', 'not allowed as child of element', 'element in scope but a * end tag seen', 'Duplicate ID ', 'The first occurrence of ID ', 'Duplicate attribute ', 'End tag * seen, but there were open elements', 'Stray end tag ', 'inside comment', 'End of file seen and there were open elements', 'not allowed on element ', 'is missing one or more of the following attributes', 'seen but an element of the same type was already open', 'Fatal Error', 'No space between attributes', 'Saw " when expecting an attribute name', 'is missing a required instance of child element ', 'Quote " in attribute name. Probable cause: Matching quote missing somewhere earlier', 'consecutive hyphens in a comment'] # 検索するフレーズ 8 9for filename in os.listdir('input'): 10 base, ext = os.path.splitext(filename) 11 # inputフォルダ内のtxtファイルを順に取得しそれぞれに検索をかける 12 if ext == '.txt': 13 with open(fr'input\{filename}', 'rb') as moto: 14 b = moto.read() 15 enc = detect(b) # txtファイルの文字コードを調べる 16 with open(f'input\{filename}', 'r', encoding=enc['encoding']) as file: 17 lines = file.readlines() 18 for line in lines: 19 for errors in errorlist: 20 if errors in line: 21 results.write(line) 22 results.write(lines[lines.index(line) + 1]) 23 results.write(lines[lines.index(line) - 1]) 24 # 検索フレーズを含む行と、その前後1行ずっつを抽出しoutput.txtに保存する 25results.close()
試したこと
もともとはchardetを使わず、初めからUTF-8で保存したテキストファイルをUTF-8で開き操作しようとしていたのですが、その時もやはり同じデコードのエラーが表示されてしまっていました。
上記コードは、それに対処しようとchardetを追加したものです。
宜しくお願いします。
エラーコードを見ると、そのファイルはCP932(ShiftJIS)と判断されているようですが、「初めからUTF-8で保存したテキストファイルをUTF-8で開き操作」ということから、ファイルはUTF-8なのですよね。chardetで正しく判定できていないのだと思います。
chardetを使う前のうまくいかないコードも提示していただけますか。
はい、基本的にinputフォルダにはウェブページを全選択・コピーしてメモ帳に張り付け、UTF-8で保存したものが格納されています。
元のコードは単純にchardetを抜いたものなのですが、下記の通りです。
"""python 3.10.7
...
for filename in os.listdir('input'):
base, ext = os.path.splitext(filename)
if ext == '.txt':
with open(f'input\{filename}', 'r', encoding='UTF-8') as file:
lines = file.readlines()
for line in lines:
for errors in errorlist:
if errors in line:
results.write(line)
results.write(lines[lines.index(line) + 1])
results.write(lines[lines.index(line) - 1])
results.close()
"""
宜しくお願いします。
エラーメッセージが部分的にしか書いてませんが、lines = file.readlines() の行のエラーに間違いないですか?
2022/09/21 15:43 のコメントのコードの時のエラーメッセージをコピペしてください。
失礼しました。
下記、エラーコード全文です。
Traceback (most recent call last):
File "C:\Users\xxx\desktop\text-search.py", line 17, in <module>
lines = file.readlines()
UnicodeDecodeError: 'cp932' codec can't decode byte 0xe1 in position 7: illegal multibyte sequence
宜しくお願いします。
不明な結果ですね。
通常は「with open(f'input\{filename}', 'r', encoding='UTF-8') 」こうなっているのに「UnicodeDecodeError: 'cp932' codec」 こうはなりません。
もしかすると、編集しているファイルと実行しているファイルが異なるというようなことはありませんか?
実行されているファイルは「desktop\text-search.py」とあるようにデスクトップ上にあるファイルのようです。
ちなみに、質問への回答はここに書くのでなく、質問そのものを編集してください。
後から見に来たひとにも伝わるし、質問欄ではコードがフォーマットできませんので。
> もともとはchardetを使わず、初めからUTF-8で保存したテキストファイルをUTF-8で開き操作しようとしていたのですが、その時もやはり同じデコードのエラーが表示されてしまっていました。
このエラーに対処するべきなのですが、対処する方法を間違えて、その間違えた対処方法について質問してしまったので解決が遠い、ということかと思います。
おそらく「同じデコードのエラー」ではなかったかと。
ありがとうございます。
編集・読み取りファイルは合わせていますし、対処前も同じエラーコードになってしまうのですが...。
もしかしたら使用中の環境やテキストファイルそのものに問題があるのかもしれないので、もう少し状況を変えながら試してみたいと思います。
実行してるコードに間違いがなく open(f'input\{filename}', 'r', encoding='UTF-8') が実行されているなら、「同じエラーコード」UnicodeDecodeError: 'cp932' codec can't decode byte 0xe1 in position 7 が出るとは思えません。
すでに指摘がありますが、「対処前も同じエラーコードになってしまう」なら「実行しているコードと編集している(見ている)コードが別」という可能性か、「同じエラーコードという認識が間違っている(実際は違うエラーがでている)」という可能性が高いと思われます。
https://teratail.com/help/question-tips#questionTips34
> 実際に起きた結果を示しましょう。例えば、「○○というエラーが表示された」「レイアウトがこのように崩れてしまった」等です。あなたの想像ではなく、実際に起きたことを述べましょう。
> 実際に起きたことと、あなたの予想をはっきり分けて書きましょう。
> 表示されたエラーメッセージをそのままコピー&ペーストしましょう。自分でタイプしなおしたり、自分で解釈・要約しようとしてはいけません。
実のところ「同じエラーコードになってしまう」という文は、間違いなくコピーされたものが提示されない限り、回答者側からは「解釈」にしか見えないのです。
"実行しているつもりのコード" と "省略されていないエラー" を "正しい組み合わせ" で "遺漏なく"、質問を編集してコピーしてみたらいいんじゃないでしょうか。
情報は質問を編集して書いたらいい、もすでに指摘されていることですよね。
あなたの回答
tips
プレビュー