使用python请求下载CSV

使用python请求下载CSV,python,csv,python-requests,Python,Csv,Python Requests,这是我的密码: 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.er

这是我的密码:

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文件最有效的方法是什么。 以及如何下载

谢谢

这应该会有帮助:

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)
输出样本:

['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
),其他答案也很有用。

通过一点搜索,我知道文件应该以通用换行模式打开,这是您无法直接使用响应内容(我想)的

要完成任务,您可以将下载的内容保存到临时文件中,也可以在内存中进行处理

另存为文件:

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)
内存中:


(待更新)

如果文件非常大,您可以使用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)

为了简化这些答案,并在下载大文件时提高性能,下面的方法可能会更有效

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\u line()
传递给csv.reader()时,我们将传递给csv.reader()。通过这样做,我们使csv.reader()能够在响应中的每一行上用
惰性地迭代reader中的行

这样可以避免在开始处理之前将整个文件加载到内存中,从而大大减少大型文件的内存开销。

您还可以使用来迭代
{'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)
我喜欢和的答案。我只能通过进一步缩短、删除多余部分、使用真实数据源、使其与2.x和3.x兼容以及保持其他地方所见的高内存效率来改进它们:

import csv
import requests

CSV_URL = 'http://web.cs.wpi.edu/~cs1004/a16/Resources/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)
糟糕的是,3.x在CSV方面没有那么灵活,因为迭代器必须发出Unicode字符串(而
请求
则发出
字节
),而CSV.reader(r.iter_lines()):
中的行的2.x版本-
-更具Pythonic风格(更短,更易于阅读)。无论如何,请注意,上面的2.x/3.x解决方案无法处理OP描述的情况,即在读取的数据中发现一个换行符没有引号

关于OP关于下载(与处理)实际CSV文件的问题,这里有另一个脚本,2.x和3.x兼容、最小、可读且内存高效:

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+'\n'.encode())

以下方法对我很有效。我也不需要使用
csv.reader()
csv.writer()
函数,我觉得这样可以使代码更干净。该代码与Python2和Python3兼容

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)
注意-six是一个帮助编写与Python2和Python3兼容的代码的包。有关六种语言的更多详细信息,请参见-

我使用此代码(我使用Python 3):

导入csv
输入io
导入请求
url=”http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv"
r=请求。获取(url)
r、 encoding='utf-8'#如果服务器未发送(或未正确发送)编码,则非常有用
csvio=io.StringIO(r.text,newline=”“)
数据=[]
对于csv.DictReader(csvio)中的行:
data.append(行)
Python3支持的代码

    with closing(requests.get(PHISHTANK_URL, stream=True})) as r:
        reader = csv.reader(codecs.iterdecode(r.iter_lines(), 'utf-8'), delimiter=',', quotechar='"')
        for record in reader:
           print (record)

这对我很有效:

from csv import DictReader

f = requests.get('https://somedomain.com/file').content.decode('utf-8')
reader = DictReader(f.split('\n'))
csv_dict_list = list(reader)

我还必须
导入编解码器
并将
r.iter_行()
包装在
codecs.iterdecode()
中,就像这样:
codecs.iterdecode(r.iterlines(),'utf-8')
。。。为了解决
byte
vs
str
问题,unicode解码问题和通用新行问题。谢谢@IrvinH,我遇到了同样的问题。顺便说一句,它应该是r.iter_lines(),你错过了下划线。在Python3.7上,这会导致:错误:迭代器应该返回字符串,而不是字节(你是在文本模式下打开文件的吗?)?这似乎是不可伸缩的。最好的答案!适用于最新版本的Python。为了支持最广泛的受众,它应该适用于所有当前部署的Python版本,而不仅仅是最新版本。。。thx虽然如此!:-)(min版本为2.6)对于下载,我认为大多数用户都希望
f.write(line+'\n'.encode())
-目前,您的示例编写了一行巨大的代码,CSV readerThx很难将其加载回内存中,以发现这一点。我通常试图利用文本文件带来的“免费”
\n
,但忽略了值得尊敬的库删除这些文件是为了清理数据,这要求我们在创建自己的文件时将它们添加回去。