2016-02-12 2 views
11

Вот мой код:запросов Используйте питона, чтобы загрузить 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') 

Это дает мне доступ к файлу CSV. Я попробовал другой метод, чтобы иметь дело с загрузкой:

Это даст файл CSV-в одной строке:

print download.content 

Эта печать первой строки и возвращает ошибку: _csv.Error: символ новой строки видно в некотируемого поле

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

Это напечатает письмо в каждой строке, и она не будет печатать всю вещь:

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

Вопрос в том, что является самым эффективным способом чтения csv-файла в этой ситуации. И как загрузить фактический файл csv.

благодаря

ответ

20

Это должно помочь:

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 образец:

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

родственный вопрос с ответом: https://stackoverflow.com/a/33079644/295246


Edit: OTH ответы могут быть полезны, если вам нужно загрузить большие файлы (т. stream=True).

+0

splitlines() !! Это работает, спасибо, сэр. – viviwill

1

Из небольшого поиска, что я понимаю, файл должен быть открыт в универсальном режиме новой строки, который вы не можете напрямую делать с контентом ответа (я думаю).

Для завершения задачи вы можете либо сохранить загруженный контент во временный файл, либо обработать его в памяти.

Сохранить как файл:

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) 

В памяти:

(будет обновляться)

0

Вы можете обновить принятый ответ с помощью метода iter_lines запросов, если файл очень большой

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

Чтобы упростить эти ответы и повысить производительность при загрузке g большой файл, ниже может работать немного более эффективно.

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 

Устанавливая stream=True в запросе GET, когда мы переходим к r.iter_lines() csv.reader(), мы пропускание generator в csv.reader(). Поступая таким образом, мы разрешаем csv.reader() лениво перебирать по каждой строке в ответе for row in reader.

Это позволяет избежать загрузки всего файла в память до того, как мы начнем его обрабатывать, резко уменьшив накладные расходы памяти для больших файлов.

+5

Мне пришлось также «импортировать кодеки» и обернуть 'r.iter_lines()' внутри 'codecs.iterdecode()' так: 'codecs.iterdecode (r.iterlines(), 'utf-8')' .. , чтобы решить проблемы 'byte' vs' str', проблемы декодирования Unicode и проблемы с универсальными новыми линиями. –

+0

Спасибо @IrvinH. , Я столкнулся с той же проблемой. Кстати, это должно быть r.iter_lines(), вы пропустили знак подчеркивания. – linqu

3

Вы также можете использовать DictReader итерировать словари {'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)