it-swarm.com.de

Verwenden Sie Python-Anforderungen, um CSV herunterzuladen

Hier ist mein Code: 

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

Dies gibt mir den Zugriff auf die CSV-Datei. Ich habe eine andere Methode ausprobiert, um mit dem Download umzugehen:

Dadurch wird die CSV-Datei in einer Zeichenfolge angegeben:

print download.content

Dies gibt die erste Zeile aus und gibt einen Fehler zurück: _csv.Error: neues Zeilenzeichen, das in einem Feld ohne Anführungszeichen steht

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

Dadurch wird in jeder Zeile ein Buchstabe gedruckt, und das Ganze wird nicht gedruckt:

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

Meine Frage ist, was ist der effizienteste Weg, um eine CSV-Datei in dieser Situation zu lesen. .__ Und wie man die eigentliche CSV-Datei herunterlädt.

vielen Dank 

19
viviwill

Das sollte helfen:

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 Probe:

['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']
[...]

Verwandte Frage mit Antwort: https://stackoverflow.com/a/33079644/295246


Bearbeiten: Andere Antworten sind hilfreich, wenn Sie große Dateien herunterladen müssen (d. H. stream=True).

39
HEADLESS_0NE

Um diese Antworten zu vereinfachen und die Leistung beim Herunterladen einer großen Datei zu verbessern, funktioniert das folgende Beispiel möglicherweise etwas effizienter. 

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   

Durch die Einstellung von stream=True in der GET-Anforderung übergeben wir einen generator an csv.reader (), wenn wir r.iter_lines() an csv.reader () übergeben. Auf diese Weise ermöglichen wir es csv.reader (), in jeder Antwort in der Antwort mit for row in reader faul zu iterieren. 

Dadurch wird vermieden, dass die gesamte Datei vor dem Verarbeiten in den Speicher geladen wird. Dadurch wird der Speicheraufwand für große Dateien drastisch reduziert.

14
The Aelfinn

Sie können auch die DictReader verwenden, um Wörterbücher von {'columnname': 'value', ...} zu durchlaufen.

import csv
import requests

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

Ich mag die Antworten aus The Aelfinn und aheld . Ich kann sie nur verbessern, indem Sie etwas mehr verkürzen, überflüssige Teile entfernen, eine echte Datenquelle verwenden, 2.x- und 3.x-kompatibel machen und die hohe Speichereffizienz beibehalten, die anderswo zu finden ist:

import csv
import requests

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

with requests.get(CSV_URL, stream=True) as r:
    lines = (line.decode('utf-8') for line in r.iter_lines())
    for row in csv.reader(lines):
        print(row)

Schade, dass 3.x weniger CSV-fähig ist, da der Iterator Unicode-Zeichenfolgen ausgeben muss (während requestsbytes), da die 2.x-only-Version - for row in csv.reader(r.iter_lines()): - mehr Pythonic ist (kürzer und lesbarer ). Beachten Sie jedoch, dass die oben beschriebene 2.x/3.x-Lösung die vom OP beschriebene Situation nicht bewältigt, in der eine NEWLINE in den gelesenen Daten nicht in Anführungszeichen steht.

Für den Teil der OP-Frage nach downloading (vs. Verarbeitung) der tatsächlichen CSV-Datei ist hier ein weiteres Skript, das that, 2.x & 3.x-kompatibel, minimal lesbar und speicherfähig macht -effizient:

import os
import requests

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

with open(os.path.split(CSV_URL)[1], 'wb') as f, \
        requests.get(CSV_URL, stream=True) as r:
    for line in r.iter_lines():
        f.write(line)
3
wescpy

Ich benutze diesen Code (ich benutze Python 3):

import csv
import io
import requests

url = "http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv"
r = requests.get(url)
r.encoding = 'utf-8'  # useful if encoding is not sent (or not sent properly) by the server
csvio = io.StringIO(r.text, newline="")
data = []
for row in csv.DictReader(csvio):
    data.append(row)
2
Michal Skop

Nach einer kleinen Suche sollte die Datei im universellen Newline-Modus geöffnet werden, was ich nicht direkt mit einem Antwortinhalt tun kann (ich denke mal).

Um die Aufgabe abzuschließen, können Sie den heruntergeladenen Inhalt entweder in einer temporären Datei speichern oder im Speicher verarbeiten.

Speichern als Datei:

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 Erinnerung:

(Aktualisiert werden)

2
Ares Ou

Sie können die akzeptierte Antwort mit der iter_lines-Methode für Anforderungen aktualisieren, wenn die Datei sehr groß ist

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)
1
aheld

Der folgende Ansatz hat für mich gut funktioniert. Ich brauchte auch keine csv.reader()- oder csv.writer()-Funktionen, was den Code sauberer macht. Der Code ist mit Python2 und Python 3 kompatibel.

from six.moves import urllib

DOWNLOAD_URL = "https://raw.githubusercontent.com/gjreda/gregreda.com/master/content/notebooks/data/city-of-chicago-salaries.csv"
DOWNLOAD_PATH ="datasets\city-of-chicago-salaries.csv" 
urllib.request.urlretrieve(URL,DOWNLOAD_PATH)

Hinweis - six ist ein Paket, das beim Schreiben von Code hilft, der mit Python 2 und Python 3 kompatibel ist. Weitere Informationen zu sechs finden Sie unter - Was macht from six.moves import urllib in Python?

0
aamir23