繁体   English   中英

在Python中解析异常的CSV文件

[英]Parsing unusal csv file in Python

我的朋友请我帮助他解析eBay csv文件并仅保存几个重要字段,因此我认为这将是学习Python(目前主要使用C编写)的好机会。

问题是,eBay 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[]结果一样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',
        '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']}

而不是将第一行作为其他行中交易的键。

我阅读了Python CSV手册,看了一些示例,搜索了Stack Overflow,但我仍然不知道下一步该怎么做-其中大多数涵盖了更“标准”的csv版本。

任何使我朝正确方向前进的提示都将是很棒的。

这很奇怪...您的代码没有给我您所提问题中的错误(尽管我使用的是Python 2.7,而您似乎使用的是3.x,也许就是因为这个原因)。

另外,文件不是以空白(空行)开头,是吗? 如果确实如此,它将与csv模块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类为您所做的工作(使用第一个非空行作为键,其余非空行作为值):

import csv

filename = "SalesHistory.csv"
read_dcts = []
keys = []
with open(filename, 'r') as csvfile:
    reader = csv.reader(csvfile, quotechar='"', skipinitialspace=True)
    for i, row  in enumerate(reader):
        try:
            if len(row) == 0:
                raise IndexError("Row %d is empty. Should skip" % (i + 1))
            if len(keys) == 0:
                keys = [ val.decode('utf-8') for val in row ]
            elif len(row) == len(keys):
                utf_dict = dict(zip(keys, [ val.decode('utf-8') for val in row ]))
                read_dcts.append(utf_dict)
        except (IndexError, AttributeError), e:
            print "Weird line %d found (got %s)" % ((i + 1), e)

# 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)

合理的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM