2016-02-12 118 views
11

這裏是我的代碼:使用Python請求下載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) 

輸出繼電器樣本:https://stackoverflow.com/a/33079644/295246


編輯:超視距

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

與回答相關問題如果您需要下載大文件(如: 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 

通過在GET請求中設置stream=True,當我們通過r.iter_lines()到csv.reader(),我們傳遞一個generator到csv.reader()。通過這樣做,我們使csv.reader()能夠在for row in reader的響應中對每一行進行延遲迭代。

這樣可以避免在開始處理整個文件之前將整個文件加載到內存中,從而大幅度減少大文件內存開銷

+5

我還必須'導入編解碼器'並在'codecs.iterdecode()'內包裝'r.iter_lines()',就像這樣:'codecs.iterdecode(r.iterlines(),'utf-8')'.. 。爲了解決'byte'和'str'問題,unicode解碼問題和通用的新線問題。 –

+0

謝謝@Ivinvin。 ,我遇到了同樣的問題。順便說一句,它應該是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)