2016-07-14 3 views
7

これは私の最初の質問です。しかし、あなたは数年の間にたくさんのプロジェクトをまとめて保存しました。私はすでに自宅にいます。Python 3.5 utf-8のファイルのUnicodeDecodeError(言語は 'ang'、Old English)

私はPython3.5とnltkを使って、古英語の完全コーパスを解析しました。これは、77個のテキストファイルとTEI形式のコーパスの連続したセグメントとしてファイルシーケンスを指定するXMLドキュメントとして公開されました。ここでは、あることを示すXMLドキュメントからヘッダの関連する部分は、TEIと協力し、実際には、です:

<?xml version="1.0" encoding="UTF-8"?> 
<TEI xmlns="http://www.tei-c.org/ns/1.0"> 
    <teiHeader type="ISBD-ER"> 
    <fileDesc> 

右、テストは、私はちょうどコーパスを開くには、NLTKのMTECorpusReaderを使用しようとしているように、 words()メソッドを使って私がそれを開くことができることを証明してください。私は対話的なPythonシェルからこのすべてをやっています。テストを簡単にするためです。

# import the reader method  
import nltk.corpus.reader as reader 

# open the sequence of files and the XML doc with the MTECorpusReader  
oecorpus = reader.mte.MTECorpusReader('/Users/me/Documents/0163','.*') 

# print the first few words in the corpus to the interactive shell 
oecorpus.words() 

私は、私は以下のトレースバックを得ることを試みる:私は勇敢なStackOverflowsketeerだとして、それで

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/util.py", line 765, in __repr__ 
    for elt in self: 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/corpus/reader/util.py", line 397, in iterate_from 
    for tok in piece.iterate_from(max(0, start_tok-offset)): 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/corpus/reader/util.py", line 291, in iterate_from 
    tokens = self.read_block(self._stream) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/corpus/reader/mte.py", line 25, in read_block 
    return list(filter(lambda x: x is not None, XMLCorpusView.read_block(self, stream, tagspec, elt_handler))) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/corpus/reader/xmldocs.py", line 307, in read_block 
    xml_fragment = self._read_xml_fragment(stream) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/corpus/reader/xmldocs.py", line 252, in _read_xml_fragment 
    xml_block = stream.read(self._BLOCK_SIZE) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/data.py", line 1097, in read 
    chars = self._read(size) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/data.py", line 1367, in _read 
    chars, bytes_decoded = self._incr_decode(bytes) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/nltk/data.py", line 1398, in _incr_decode 
    return self.decode(bytes, 'strict') 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 59: invalid start byte 

は、私はどちらかと判断しましたここで私が実際にやっているすべてですまたはそれ以上のファイルが壊れているか、Pythonのutf-8デコーダが処理方法を知らない文字が含まれているファイルに文字があります。私は、このファイルの整合性(それは私の言葉を取る)のかなり確信することができますので、私は、私は明白な効果で77個のテキストファイルを再フォーマットするには、以下のしようとした

を追求しています。だから私の

for file in loglist: 
    bufferfile = open(file, encoding='utf-8', errors='replace') 
    bufferfile.close() 
loglist = [name for name in os.listdir('.') if os.path.isfile(name)] 

質問は次のとおりです

1)これまでのところ私のアプローチは理にかなっていますか、それともこれまでのトラブルシューティングで何かを苦労しましたか?

2)この時点では、UTF-8エラーが非常に早く(16進数の59桁目に)現れているという事実と、私のutf -8エラー置換スクリプトは問題に何の違いもありませんでしたか?私がそれを仮定するのが間違っているなら、どのようにすれば問題をより良く分離することができますか?

3)問題がXML文書であると判断できる場合は、それを消去する最善の方法は何ですか?その16進数のバイトとそれに対応するASCII文字を見つけようとするのは可能でしょうか?

ありがとうございました!

+0

試してみるべきこと:文字エンコーディングを自動検出するテキストエディタまたはWebブラウザで文書を開くと、その文書がどのエンコーディングにあると思いますか? –

+1

XMLファイルが有効なUTF-8ファイルではないようです。この問題を解決するには、ファイルの実際のエンコーディング(迷惑な部分になります)を見つけて、そのエンコーディングでプレーンテキストとしてファイルを読み取り、それをUTF-8として保存して、有効なUTF -8エンコードされたXMLファイル。 XMLファイルにはバイナリ(CDATA)セクションはありません。 – Evert

+0

どうもありがとうございます。XML文書に関する私の疑惑を確認してくれてありがとう。 XML文書の先頭にあるヘッダーは、エンコーディングがutf-8であることを示しています。実際にUTF-8エンコーディングでSublime Textで開くことができます。私のツールが実際にはあまりにもうまく機能していて、私のエンコーディングを自動的に変換しているのかどうかは不思議です...もう少し詳しく説明しますが、これまでのところUTF-編集者は何の違いもありません。 – gatsbysghost

答えて

4

ファイルを読んだり再度書き込んだりしても、変換テクニックが動作しませんでした。

0x80は、UTF-8またはiso-8859- *文字セットの有効なバイトではありません。 Windowsのコードページでは有効ですが、Unicodeのみで英語の古い文字をサポートできるため、データが非常に壊れています。悪いバイトをUTF-8に変換するために

ん:

with open('input.txt', 'r', encoding='utf-8', errors='ignore') as input, 
     open('output.txt', 'w', encoding='utf-8') as output: 

    output.write(input.read()) 

あなたはデータを失うことを気にしないのであれば、あなたはMTECorpusReader上encoding引数使用して逃げることがあります。

oecorpus = reader.mte.MTECorpusReader('/Users/me/Documents/0163','.*', encoding='cp1252') 

0x80はユーロ(€)記号になります。

+1

彼は古英語のテキストでどれぐらいの人が見つかるのだろうか? – patrick

+0

ああ、私はファイル内の文字セットを再フォーマットしようとしていたことが正しいとは思っていませんでした。私のPythonの無知を訂正するのを手伝ってくれてありがとう - 私はまだ学んでいます! – gatsbysghost

+0

これはすべて正しいですが、コーパスはかなり古くなっているので、欠落した記号(ð、þなど)のカスタム拡張を含む基本8-it文字セットを使用する可能性が非常に高いです。それはおそらくコーパスに付属のドキュメントにありますが、そうでなければ少し古い英語を知っていても、ファイルを調べることによって各カスタムバイトの意味を理解するのは難しくありません。それを試してみて、ファイルをカスタム8ビットエンコーディングからUnicodeに変換する方法についての質問に戻ってください(それはかなり簡単です)。 – alexis

0

NLTKではUnicodeはサポートされていません。まったく。私はそれが古い英語なら、それはいくつかの奇妙な手紙を利用する必要があると思う。

しかし、頭痛を最小限に抑えることができる解決策があります。 spacyと呼ばれるNLTKよりもかなり現代的で強力な図書館があります。 NLTKはすべてができないことを要求しながら、すべては、UnicodeのことHere's a link.

スペイシー要求。それは頭痛が伴う価値がありません。さらに、NLTKのプロセッサーはのみです。は完全にユニコードフリーの文字列でしか動作しません。

+2

キャラクターが「À」であることをどのように確認しましたか? –

+0

エラーを注意深く読んでください。 '' utf-8 'コーデックは59番目のバイト0x80をデコードできません。' utf-8の無効なバイトです。だから、それが何であるか把握することはできません。しかし、最も近い隣人は制御文字かそのシンボルです。 – Ares

+1

「0x80」に最も近い文字セットは「À」ですか? –

関連する問題