在Python中解析异常csv文件

在Python中解析异常csv文件,python,csv,Python,Csv,我的朋友让我帮他解析eBay csv文件并只保存几个重要字段,所以我认为这将是学习Python的好机会(目前主要用C编写) 问题是,易趣的csv文件格式让我很难受: Numer rekordu sprzedaży,Nazwa użytkownika,Imię i nazwisko kupującego,Numer telefonu kupującego,Adres e-mail kupującego,Adres 1 kupującego,Adres 2 kupującego,Miejsc

我的朋友让我帮他解析eBay csv文件并只保存几个重要字段,所以我认为这将是学习Python的好机会(目前主要用C编写)

问题是,易趣的csv文件格式让我很难受:

    Numer rekordu sprzedaży,Nazwa użytkownika,Imię i nazwisko kupującego,Numer telefonu kupującego,Adres e-mail kupującego,Adres 1 kupującego,Adres 2 kupującego,Miejscowość kupującego,Województwo kupującego,Kod pocztowy kupującego,Kraj kupującego,Numer przedmiotu,Nazwa przedmiotu,Etykieta niestandardowa,Ilość,Cena sprzedaży,Wysyłka i obsługa,Ubezpieczenie,Koszt płatności za pobraniem,Cena łączna,Forma płatności,Data sprzedaży,Data realizacji transakcji,Data zapłaty,Data wysyłki,Opinia wystawiona,Opinia otrzymana,Uwagi własne,Identyfikator transakcji PayPal,Usługa wysyłkowa,Opcja płatności za pobraniem,Identyfikator transakcji,Identyfikator zamówienia,Szczegóły wersji

"610","xxx","John Rodriguez","(860) 000-00000","mail@yahoo.com","0 Branford Ave Bldg 11","","City","CT","00000","Stany Zjednoczone","330972592582","Honda CBR 900 RR","","1","US $21,49","US $5,50","US $0,00","","US $26,99","PayPal","23-03-2014","23-03-2014","23-03-2014","","Nie","","","4EP58","Standard Shipping from outside US","","9639014","",""
"627","yyy","Name","063100000","mail@orange.fr","Rue barillettes","","st main","Rhône","00000","Francja","3311071","Suzuki SV 650","","1","EUR 15,99","EUR 4,00","EUR 0,00","","EUR 19,99","PayPal","31-03-2014","31-03-2014","31-03-2014","","Nie","","","6E03683046","Livraison standard ? partir de l'étranger","","9659014","",""

Pobrano rekordów: 8,,od ,23-03-2014,15:06:14, do ,11-04-2014,14:32:17
Nazwa sprzedawcy: mail@gmail.com
使用
csv.DictReader
对其进行解析,就像手册中一样,结果是每一行都像
none:list[]

import csv

filename = "SalesHistory.csv"

csvfile = open(filename, encoding="iso-8859-2")
input_file = csv.DictReader(csvfile, quotechar='"', skipinitialspace=True)

for row in input_file:
    print (row)
{None:['\tNumer rekordu sprzedaży',Nazwa użytkownika',Imięi nazwisko kupującego',Numer telefonu kupującego',
“地址:电子邮件地址:kupującego”、“地址:1 kupującego”、“地址:2 kupującego”、“Miejscowośćkupującego”,
“Województwo kupującego”、“Kod pocztowy kupującego”、“Kraj kupującego”、“Numer przedmiotu”、“Nazwa przedmiotu”,
“Etykieta NiesStandardowa”、“Ilość”、“Cena sprzedaży”、“Wysyłka i obsługa”、“Ubezpieczenie”,
“Koszt płatności za pobraniem”、“Cenałczna”、“Forma płatności”、“Data sprzedaży”,
“transakcji的数据实现”、“Data zapłaty”、“Data wysyłki”、“Opinia wystawiona”、“Opinia Otzymana”,
“Uwagi własne”、“Identityficator transakcji PayPal”、“Usługa wysyłkowa”、“Opcja płatności za pobraniem”,
“身份认证机构transakcji”、“身份认证机构zamówienia”、“Szczegóy wersji”]}
而不是将第一行作为其他行中事务的键读取

import csv

def dict_from_csv(filename):
    '''
    (file)->list of dictionaries
    Function to read a csv file and format it to a list of dictionaries.
    The headers are the keys with all other data becoming values
    '''

    #open the file and read it using csv.reader()
    #read the file. for each row that has content add it to list mf
    #the keys for our user dict are the first content line of the file mf[0]
    #the values to our user dict are the other lines in the file mf[1:]
    mf = []
    with open(filename, 'r') as f:
        my_file = csv.reader(f)
        for row in my_file:
            if any(row):
                mf.append(row)
    file_keys = mf[0]
    file_values = mf[1:]

    #Combine the two lists, turning into a list of dictionaries, using the keys list as the key and the value list as the values
    my_list = []
    for value in file_values:
        my_list.append(dict(zip(file_keys, file_values)))

    #return the list of dictionaries
    return my_list
我阅读了PythonCSV手册,查看了一些示例,搜索了堆栈溢出,但我仍然不知道下一步该怎么做——其中大多数都涉及CSV的更多“标准”版本


任何能让我朝正确方向前进的建议都会很好。

真奇怪。。。您的代码没有告诉我您在问题中发布的错误(尽管我使用的是Python2.7,而您似乎使用的是3.x,可能是因为这个原因)

而且,文件不是以空白(空行)开头的,是吗?如果它这样做了,它将搞乱
csv
模块。它使用第一行猜测
csv.DictReader
将使用的键。如果开头有一个空行,它将无法猜出钥匙。您应该在尝试使用
csv
解析文件之前“清理”该文件(删除空行应该可以做到这一点),或者您可以逐行读取跳过空行,但这会使使用
csv.DictReader变得复杂(你应该得到第一个非空行,考虑它的值,你的结果字典的键,然后读其余的行,考虑它的值作为结果字典的值……我只需在解析之前从文件中删除空行)

在下面的代码中,我添加了一个
try/catch
块来处理不完整的行(例如示例文件中的最后两行),但是即使没有它,它也可以正常工作

import csv

filename = "SalesHistory.csv"
read_dcts = []

with open(filename, 'r') as csvfile:
    input_file = csv.DictReader(csvfile, quotechar='"', skipinitialspace=True)
    for i, dct in enumerate(input_file):
        try:
            utf_dict=dict((k.decode('utf-8'), v.decode('utf-8')) \
                          for k, v in dct.items())
            read_dcts.append(utf_dict)
        except AttributeError:
            print "Weird line %d found" % (i + 1)

# Verify:
for i, dct in enumerate(read_dcts):
    print "Dict %d" % (i + 1)
    for k, v in dct.iteritems():
        print "\t%s: %s" % (k, v)
如果我执行上述代码,我会得到:

Weird line 3 found
Weird line 4 found
Dict 1
        Opinia otrzymana: 
        Cena sprzedaży: US $21,49
        [ . . . ]
        Wysyłka i obsługa: US $5,50
        Opcja płatności za pobraniem: 
Dict 2
        Opinia otrzymana: 
        Cena sprzedaży: EUR 15,99
        [ . . . ]
        Wysyłka i obsługa: EUR 4,00
        Opcja płatności za pobraniem
我删除了很多加载的行,只是为了清晰起见,但除此之外,它应该加载您想要的内容

如果你有更新,请通过评论让我知道

编辑:

为了防止文件包含空行,而您不想对其进行预清理,您几乎可以“手动”执行
DictReader
类为您执行的操作(使用第一个非空行作为键,其余非空行作为值):


一个合理的simlpe函数,用于读取csv文件并生成文件中第一行的键和其他行的值

import csv

def dict_from_csv(filename):
    '''
    (file)->list of dictionaries
    Function to read a csv file and format it to a list of dictionaries.
    The headers are the keys with all other data becoming values
    '''

    #open the file and read it using csv.reader()
    #read the file. for each row that has content add it to list mf
    #the keys for our user dict are the first content line of the file mf[0]
    #the values to our user dict are the other lines in the file mf[1:]
    mf = []
    with open(filename, 'r') as f:
        my_file = csv.reader(f)
        for row in my_file:
            if any(row):
                mf.append(row)
    file_keys = mf[0]
    file_values = mf[1:]

    #Combine the two lists, turning into a list of dictionaries, using the keys list as the key and the value list as the values
    my_list = []
    for value in file_values:
        my_list.append(dict(zip(file_keys, file_values)))

    #return the list of dictionaries
    return my_list

很抱歉-added@pawel.ad,你知道csv文件中的最后两行是什么吗?我很确定这会扰乱你的阅读。你需要它们吗?如果需要,你希望如何检索它们?它们似乎。。。strange@BorrajaX它们是易趣自动添加的,我不需要它们。我会先尝试删除它们,然后-也许会帮助