questa è la mia prima volta che utilizzo StackOverflow per fare una domanda, ma hai salvato collettivamente tanti dei miei progetti nel corso degli anni che Mi sento già a casa.Python 3.5 UnicodeDecodeError per un file in utf-8 (lingua è 'ang', inglese antico)
Sto usando Python3.5 e nltk per analizzare il corpus completo del vecchio inglese, che è stato pubblicato per me come 77 file di testo e un documento XML che designa la sequenza di file come segmenti contigui di un corpus in formato TEI. Ecco la parte rilevante del colpo di testa da proiezione doc XML che siamo, infatti, lavorando con TEI:
<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader type="ISBD-ER">
<fileDesc>
Giusto, quindi come un test, sto solo cercando di usare MTECorpusReader di NLTK per aprire il corpus e usa il metodo words() per dimostrare che sono in grado di aprirlo. Sto facendo tutto questo dalla shell Python interattiva, solo per facilità di test. Ecco tutto quello che sto facendo davvero:
# 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()
Quando provo che, ricevo il seguente traceback:
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
Così, come io sono uno StackOverflowsketeer coraggioso, ho stabilito che uno dei due o più file sono corrotti o c'è qualche carattere nel file (s) che contiene un carattere che il decodificatore utf-8 di Python non sa come gestire. Posso essere abbastanza certi dell'integrità di questo file (prendere la mia parola per esso), quindi sto perseguendo
ho provato quanto segue per riformattare i file di testo 77 senza alcun effetto apparente:
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)]
Quindi il mio domande sono:
1) Il mio approccio finora ha senso, o ho rovinato qualcosa nella mia risoluzione dei problemi fino ad ora?
2) È giusto concludere a questo punto che il problema deve essere con il documento XML, in base al fatto che l'errore UTF-8 si presenta molto presto (in posizione esadecimale 59) e il fatto che il mio utf -8 Lo script di sostituzione dell'errore non ha fatto alcuna differenza rispetto al problema? Se ho torto a pensarlo, allora come posso isolare meglio il problema?
3) Se possiamo concludere che il problema è con il documento XML, qual è il modo migliore per chiarirlo? È possibile per me provare a trovare quel byte esadecimale e l'ASCII a cui corrisponde e modificare il carattere?
Grazie in anticipo per il vostro aiuto!
Una cosa da provare: se si apre il documento in un editor di testo o un browser Web che rileva automaticamente le codifiche dei caratteri, quale codifica pensa che sia il documento? –
Sembra infatti che il file XML non sia un file UTF-8 valido. Solo una supposizione per risolvere questo problema: trova la codifica effettiva del file (che sarà la parte fastidiosa), leggi il file come testo normale con quella codifica, quindi salvalo come UTF-8 e potresti finire con un UTF valido -8 file XML codificato. A condizione che non ci siano sezioni binarie (CDATA) nel file XML. – Evert
Ciao a tutti - grazie per aver confermato i miei sospetti sul documento XML. Quindi l'intestazione nella parte superiore del documento XML specifica che la sua codifica è utf-8, e infatti sono in grado di aprirlo in Sublime Text con la codifica UTF-8. Mi chiedo se i miei strumenti funzionino un po 'troppo bene qui e convertiremo automaticamente le codifiche per me ... Ci giocherò un po' di più, ma finora i miei tentativi di salvare la codifica come UTF-8 da vari gli editori non fanno alcuna differenza. – gatsbysghost