2016-02-12 18 views
11

Ecco il mio codice:richieste usare Python per scaricare CSV

import csv 
import requests 
with requests.Session() as s: 
    s.post(url, data=payload) 
    download = s.get('url that directly download a csv report') 

Questo mi dà l'accesso al file CSV. Ho provato metodo diverso di affrontare il download:

Questo darà il file CSV in una stringa:

print download.content 

Questa stampa la prima riga e l'errore tornare: _csv.Error: carattere nuova linea di visto in campo non quotati

cr = csv.reader(download, dialect=csv.excel_tab) 
for row in cr: 
    print row 

Questo stamperà una lettera in ogni riga e non stamperà il tutto:

cr = csv.reader(download.content, dialect=csv.excel_tab) 
for row in cr: 
    print row 

La mia domanda è qual è il modo più efficace per leggere un file csv in questa situazione. E come scaricare il file csv effettivo.

grazie

risposta

20

Questo dovrebbe aiutare:

import csv 
import requests 

CSV_URL = 'http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv' 


with requests.Session() as s: 
    download = s.get(CSV_URL) 

    decoded_content = download.content.decode('utf-8') 

    cr = csv.reader(decoded_content.splitlines(), delimiter=',') 
    my_list = list(cr) 
    for row in my_list: 
     print(row) 

Ouput campione:

['street', 'city', 'zip', 'state', 'beds', 'baths', 'sq__ft', 'type', 'sale_date', 'price', 'latitude', 'longitude'] 
['3526 HIGH ST', 'SACRAMENTO', '95838', 'CA', '2', '1', '836', 'Residential', 'Wed May 21 00:00:00 EDT 2008', '59222', '38.631913', '-121.434879'] 
['51 OMAHA CT', 'SACRAMENTO', '95823', 'CA', '3', '1', '1167', 'Residential', 'Wed May 21 00:00:00 EDT 2008', '68212', '38.478902', '-121.431028'] 
['2796 BRANCH ST', 'SACRAMENTO', '95815', 'CA', '2', '1', '796', 'Residential', 'Wed May 21 00:00:00 EDT 2008', '68880', '38.618305', '-121.443839'] 
['2805 JANETTE WAY', 'SACRAMENTO', '95815', 'CA', '2', '1', '852', 'Residential', 'Wed May 21 00:00:00 EDT 2008', '69307', '38.616835', '-121.439146'] 
[...] 

questione connessa con la risposta: https://stackoverflow.com/a/33079644/295246


Edit: Oth Le risposte sono utili se hai bisogno di scaricare file di grandi dimensioni (ad es. stream=True).

+0

splitlines() !! Funziona, grazie signore. – viviwill

1

Da una piccola ricerca, capisco che il file debba essere aperto in modalità newline universale, che non è possibile eseguire direttamente con un contenuto di risposta (credo).

Per completare l'attività, è possibile salvare il contenuto scaricato in un file temporaneo o elaborarlo in memoria.

Salva come file:

import requests 
import csv 
import os 

temp_file_name = 'temp_csv.csv' 
url = 'http://url.to/file.csv' 
download = requests.get(url) 

with open(temp_file_name, 'w') as temp_file: 
    temp_file.writelines(download.content) 

with open(temp_file_name, 'rU') as temp_file: 
    csv_reader = csv.reader(temp_file, dialect=csv.excel_tab) 
    for line in csv_reader: 
     print line 

# delete the temp file after process 
os.remove(temp_file_name) 

In memoria:

(da aggiornare)

0

è possibile aggiornare la risposta accettata con il metodo iter_lines di richieste se il file è molto grande

import csv 
import requests 

CSV_URL = 'http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv' 

with requests.Session() as s: 
    download = s.get(CSV_URL) 

    line_iterator = (x.decode('utf-8') for x in download.iter_lines(decode_unicode=True)) 

    cr = csv.reader(line_iterator, delimiter=',') 
    my_list = list(cr) 
    for row in my_list: 
     print(row) 
7

Per semplificare queste risposte e aumentare le prestazioni durante il downloadin g un file di grandi dimensioni, il sotto potrebbe funzionare un po 'più efficientemente.

import requests 
from contextlib import closing 
import csv 

url = "http://download-and-process-csv-efficiently/python.csv" 

with closing(requests.get(url, stream=True)) as r: 
    reader = csv.reader(r.iter_lines(), delimiter=',', quotechar='"') 
    for row in reader: 
     print row 

Impostando stream=True nella richiesta GET, quando si passa a r.iter_lines() csv.reader(), stiamo passando un generator a csv.reader(). In questo modo, abilitiamo csv.reader() a scorrere lentamente su ogni riga della risposta con for row in reader.

Ciò evita il caricamento dell'intero file in memoria prima di iniziare l'elaborazione, riducendo drasticamente il sovraccarico di memoria per file di grandi dimensioni.

+5

Ho dovuto anche "importare i codec" e racchiudere "r.iter_lines()" all'interno di "codecs.iterdecode()" così: 'codecs.iterdecode (r.iterlines(), 'utf-8')' .. per risolvere i problemi di 'byte' vs' str', problemi di decodifica unicode e problemi di nuova linea universale. –

+0

Grazie a @IrvinH. , Mi sono imbattuto nello stesso problema. btw dovrebbe essere r.iter_lines() hai perso il carattere di sottolineatura. – linqu

3

È inoltre possibile utilizzare il DictReader per iterare dizionari di {'columnname': 'value', ...}

import csv 
import requests 

response = requests.get('http://example.test/foo.csv') 
reader = csv.DictReader(response.iter_lines()) 
for record in reader: 
    print(record)