Novamente: UnicodeEncodeError: codec ascii não pode codificar
Eu tenho uma pasta de arquivos XML que gostaria de analisar. Eu preciso tirar o texto dos elementos desses arquivos. Eles serão coletados e impressos em um arquivo CSV onde os elementos são listados em colunas.
I posso realmente fazer isso agora paraalguns dos meus arquivos. Isto é, para muitos dos meus arquivos XML, o processo corre bem e eu recebo a saída que desejo. O código que faz isso é:
import os, re, csv, string, operator
import xml.etree.cElementTree as ET
import codecs
def parseEO(doc):
#getting the basic structure
tree = ET.ElementTree(file=doc)
root = tree.getroot()
agencycodes = []
rins = []
titles =[]
elements = [agencycodes, rins, titles]
#pulling in the text from the fields
for elem in tree.iter():
if elem.tag == "AGENCY_CODE":
agencycodes.append(int(elem.text))
elif elem.tag == "RIN":
rins.append(elem.text)
elif elem.tag == "TITLE":
titles.append(elem.text)
with open('parsetest.csv', 'w') as f:
writer = csv.writer(f)
writer.writerows(zip(*elements))
parseEO('EO_file.xml')
No entanto, em algumas versões do arquivo de entrada, recebo o erro infame:
'ascii' codec can't encode character u'\x97' in position 32: ordinal not in range(128)
O traceback completo é:
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
<ipython-input-15-28d095d44f02> in <module>()
----> 1 execfile(r'/parsingtest.py') # PYTHON-MODE
/Users/ian/Desktop/parsingtest.py in <module>()
91 writer.writerows(zip(*elements))
92
---> 93 parseEO('/EO_file.xml')
94
95
/parsingtest.py in parseEO(doc)
89 with open('parsetest.csv', 'w') as f:
90 writer = csv.writer(f)
---> 91 writer.writerows(zip(*elements))
92
93 parseEO('/EO_file.xml')
UnicodeEncodeError: 'ascii' codec can't encode character u'\x97' in position 32: ordinal not in range(128)
Estou bastante confiante de ler os outros segmentos que o problema está no codec sendo usado (e, você sabe, o erro é bem claro sobre isso também). No entanto, as soluções que li não ajudarammim (enfatizado porque eu entendo que eu sou a fonte do problema, não a maneira como as pessoas responderam no passado).
Diversas repsonses (como:este eeste eesteNão lide diretamente com o ElementTree, e não sei como traduzir as soluções para o que estou fazendo.
Outras soluções que lidam com ElementTree (como:este eeste) estão usando uma string curta (o primeiro link aqui) ou estão usando os métodos .tostring / .fromstring no ElementTree, o que eu não faço. (Embora, claro, talvez eu deva ser.)
Coisas que eu tentei que não funcionaram:
Eu tentei trazer o arquivo via codificação UTF-8:
infile = codecs.open('/EO_file.xml', encoding="utf-8")
parseEO(infile)
mas eu acho que o processo ElementTree já entende que ele é UTF-8 (o que é observado na primeira linha de todos os arquivos XML que eu tenho), e isso não só não está correto, mas é redundantemente ruim novamente.
Eu tentei declarar um processo de codificação dentro do loop, substituindo:
tree = ET.ElementTree(file=doc)
com
parser = ET.XMLParser(encoding="utf-8")
tree = ET.parse(doc, parser=parser)
no loop acima que funciona. Isso não funcionou para mim também. Os mesmos arquivos que funcionavam antes ainda funcionavam, os mesmos arquivos que criaram o erro ainda criavam o erro.
Houve muitas outras tentativas aleatórias, mas não vou insistir no assunto.
Então, embora eu assuma que o código que eu tenho é ineficiente e ofensivo para um bom estilo de programação, ele faz o que eu quero para vários arquivos. Eu estou tentando entender se há simplesmente um argumento que eu estou perdendo que eu não sei, se eu deveria de alguma forma pré-processar os arquivos (eu não identifiquei onde o caractere ofensivo é, mas sei que você \ " x97 se traduz em um caractere de controle de algum tipo), ou alguma outra opção.