簡體   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