PassarByteOrderMarker(BOM)

Para quem já tentou trabalhar com arquivos CSV no Python, pode te tido algum tipo de problema ao ler .csv gerados em plataforma Windows.

Acontece, que criando o arquivo pelo notepad (por exemplo), ele insere no cabeçalho o Byte-Order Marker (BOM) para identificar que esse tipo de arquivo é UTF8, mas consequentemente, sabemos também que foi gerado no Windows (uma vez que apenas ele insere esse byte). Sendo assim, ao ler com a biblioteca do CSV do Python, ele dá um erro logo no primeira linha - consequência do byte -. Abaixo, um código encontrado na web e que realmente resolve o problema, infelizmente não tenho exatamente como dar os crédito pois não consegui claramente o criador do código.

   1 import os, codecs, csv, pdb
   2 def byPassBombChar(filename, mode='r', encoding = 'utf-8'):
   3 
   4         hasBOM = False
   5         if os.path.isfile(filename):
   6                 f = open(filename,'rb')
   7                 header = f.read(4)
   8                 f.close()
   9 
  10                 # Don't change this to a map, because it is ordered
  11                 encodings = [ ( codecs.BOM_UTF32, 'utf-32' ),
  12                         ( codecs.BOM_UTF16, 'utf-16' ),
  13                         ( codecs.BOM_UTF8, 'utf-8' ) ]
  14 
  15                 for h, e in encodings:
  16                         if header.startswith(h):
  17                                 encoding = e
  18                                 hasBOM = True
  19                                 break
  20 
  21         f = codecs.open(filename,mode,encoding)
  22         # Eat the byte order mark
  23         if hasBOM:
  24                 f.read(1)
  25         return f
  26 
  27 if __name__ == "__main__":
  28     fpath = "/home/sua.pasta/arquivo_teste.csv"
  29 
  30     for row in csv.reader(byPassBombCharWithFile(open(fpath))):
  31         print row

PassarByteOrderMarker(BOM) (editada pela última vez em 2010-01-13 23:32:24 por ThiagoHolanda)