Voici mon 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')
Cela me donne l’accès au fichier csv. J'ai essayé différentes méthodes pour gérer le téléchargement:
Cela donnera le fichier csv en une chaîne:
print download.content
Ceci imprime la première ligne et renvoie l'erreur: _csv.Error: le caractère de nouvelle ligne vu dans un champ sans guillemets
cr = csv.reader(download, dialect=csv.Excel_tab)
for row in cr:
print row
Ceci imprimera une lettre dans chaque rangée et n'imprimera pas le tout:
cr = csv.reader(download.content, dialect=csv.Excel_tab)
for row in cr:
print row
Ma question est quelle est la manière la plus efficace de lire un fichier csv dans cette situation. .__ Et comment télécharger le fichier csv actuel.
merci
Cela devrait aider:
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)
Échantillon de sortie:
['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']
[...]
Question connexe avec réponse: https://stackoverflow.com/a/33079644/295246
Éditer: d’autres réponses sont utiles si vous devez télécharger des fichiers volumineux (c.-à-d. stream=True
).
Pour simplifier ces réponses et augmenter les performances lors du téléchargement d'un fichier volumineux, les éléments ci-dessous peuvent fonctionner un peu plus efficacement.
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
En définissant stream=True
dans la requête GET, lorsque nous passons r.iter_lines()
à csv.reader (), nous transmettons un générateur à csv.reader (). Ce faisant, nous permettons à csv.reader () de parcourir par la suite chaque ligne de la réponse avec for row in reader
.
Cela évite de charger tout le fichier en mémoire avant le traitement, ce qui réduit considérablement la surcharge de mémoire pour les fichiers volumineux.
Vous pouvez également utiliser DictReader
pour itérer les dictionnaires de {'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)
J'aime les réponses de The Aelfinn et aheld . Je ne peux les améliorer qu'en raccourcissant un peu plus, en supprimant les éléments superflus, en utilisant une source de données réelle, en la rendant compatible 2.x et 3.x et en maintenant le niveau élevé d'efficacité de la mémoire observé ailleurs:
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)
Dommage que 3.x soit moins souple en CSV car l'itérateur doit émettre des chaînes Unicode (alors que requests
fait bytes
) car la version uniquement 2.x --for row in csv.reader(r.iter_lines()):
- est plus pythonique (plus courte et facile à lire). Quoi qu'il en soit, notez que la solution 2.x/3.x ci-dessus ne gérera pas la situation décrite par l'OP dans laquelle une NEWLINE est trouvée non citée dans la lecture des données.
Pour la partie de la question de l'OP concernant le téléchargement (par rapport au traitement) du fichier CSV lui-même, voici un autre script compatible avec that, compatible 2.x et 3.x, minimal, lisible et mémoire. -efficace:
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)
Si j'ai bien compris, le fichier devrait être ouvert en mode newline universel, ce que vous ne pouvez pas faire directement avec un contenu de réponse (je suppose).
Pour terminer la tâche, vous pouvez soit enregistrer le contenu téléchargé dans un fichier temporaire, soit le traiter en mémoire.
Enregistrer en tant que fichier:
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)
En mémoire:
(À mettre à jour)
Vous pouvez mettre à jour la réponse acceptée avec la méthode iter_lines de requêtes si le fichier est très volumineux.
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)
L'approche suivante a bien fonctionné pour moi. Je n'ai pas non plus besoin d'utiliser les fonctions csv.reader()
ou csv.writer()
, ce qui, à mon avis, rend le code plus propre. Le code est compatible avec Python2 et Python 3.
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)
Remarque - six est un paquetage qui aide à l'écriture de code compatible avec Python 2 et Python 3. Pour plus d'informations sur six, voir - Que fait from six.moves import urllib
en Python?