我已阅读与unicode阅读相关的每个帖子,但我似乎无法让它工作。
我试图读取一个恰好在其上有utf-8 BOM签名的csv,也是utf-8。
所以,在打开文件后,用unicodecsv库读取它,我尝试了不同的东西。
def _extract_gz(self): # fd
logging.info("Gz detected")
self.fp = gzip.open(self.path)
return unicodecsv.reader(self.path.read().decode('utf-8-sig').splitlines(), encoding='utf-8')
仍然在第226行失败.UnicodeEncodeError:'ascii'编解码器无法编码位置226中的字符u'\ xf1':序数不在范围内(128)
也试过这种方法,但也失败了。
def _extract_gz(self): # fd
logging.info("Gz detected")
self.fp = gzip.open(self.path)
self.f = self.unicode_csv_reader()
return self.f
def unicode_csv_reader(self):
csv_reader = csv.reader(self.fp.read().decode('utf-8-sig').splitlines())
for row in csv_reader:
yield [cell.encode('utf-8', 'replace') for cell in row]
我做错了什么?
谢谢大家。
版本是 Python 2.7.12
答案 0 :(得分:1)
内置的csv
模块不支持Unicode(假设是Python 2.x),但是有一个替换unicodecsv
模块可以做(并且你已经尝试过了,不成功),它应该是相当简单的:
import gzip
import unicodecsv as csv
def read_csv(filename, has_bom=True, **kwargs):
with gzip.open(filename, "r") as f:
if has_bom:
f.seek(3) # skip the BOM
reader = csv.reader(f, **kwargs)
for row in reader:
yield row
for row in read_csv("path/to/your.csv.gz", delimiter=";"): # encoding needed for BOM
print(row) # or do whatever you want with it
应该做的伎俩。
更新 - 以上代码适用于您上传的文件,并且不会引发任何错误(因为您的文件是由我添加的半列分隔的),但是unicodecsv
模块中的错误 - 在解析带有BOM的文件时,它不会删除第一列名称周围的引号,因此我更新了代码以反映该内容。
在上传的文件中运行时,您会得到以下输出(YMMV,取决于您的控制台如何打印unicode):
[u'Name', u'Ref', u'POS', u'POS', u'Status', u'City', u''] [u'Hotel Flamero', u'3365', u'ES', u'0.27', u'No Change', u'Matalascañas', u'']
(最后一个空条目是由于您的CSV将最后一个条目设为空)
UPDATE#2 - 手头没有MySQL实例,但您可以使用内存中的SQLite DB检查它是否正常解析:
import sqlite3
db = sqlite3.connect(":memory:") # create an in-memory DB
c = db.cursor()
c.execute("CREATE TABLE test (Name TEXT, Ref TEXT, POS TEXT, Status TEXT, City TEXT)")
header = None
for row in read_csv("path/to/your.csv.gz", delimiter=";"):
del row[-1] # remove the last element as it's always empty
if header is None: # get the header first
header = row
continue
query = u"INSERT INTO test ({}) VALUES ({})".format(
u", ".join(header),
u", ".join(u"'{}'".format(column) for column in row) # quote each column entry
)
c.execute(query)
# now lets read our data from the DB
c.execute("SELECT * FROM test")
for row in c.fetchall():
print(row)
幸福地打印出来:
(u'Hotel Flamero', u'3365', u'ES', u'No Change', u'Matalascañas')