首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用python请求下载CSV

使用python请求下载CSV
EN

Stack Overflow用户
提问于 2016-02-12 19:49:32
回答 12查看 176.4K关注 0票数 71

这是我的代码:

代码语言:javascript
运行
复制
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文件:

代码语言:javascript
运行
复制
print download.content

此打印第一行并返回错误:_csv.Error:在未引号字段中看到的新行字符。

代码语言:javascript
运行
复制
cr = csv.reader(download, dialect=csv.excel_tab)
for row in cr:
    print row

这将在每一行打印一封信,并且不会打印全部内容:

代码语言:javascript
运行
复制
cr = csv.reader(download.content, dialect=csv.excel_tab)
for row in cr:
    print row

我的问题是:在这种情况下,读取csv文件的最有效方法是什么?以及如何下载。

谢谢

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2016-02-12 20:14:56

这应有助于:

代码语言:javascript
运行
复制
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)

输出样本:

代码语言:javascript
运行
复制
['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

编辑:如果您需要下载大型文件(即stream=True),其他答案是有用的。

票数 112
EN

Stack Overflow用户

发布于 2016-07-30 19:13:04

为了简化这些答案,并在下载大文件时提高性能,下面的工作可能会更高效一些。

代码语言:javascript
运行
复制
import requests
from contextlib import closing
import csv
from codecs import iterdecode

url = "http://download-and-process-csv-efficiently/python.csv"

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

通过在GET请求中设置stream=True,当我们将r.iter_lines()传递给csv.reader()时,就是将生成器传递给csv.reader()。通过这样做,我们使csv.reader()能够懒洋洋地遍历for row in reader响应中的每一行。

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

票数 36
EN

Stack Overflow用户

发布于 2018-08-21 19:02:41

我喜欢艾芬恩阿卡托的答案。我只能通过缩短一些,删除多余的部分,使用真正的数据源,使其与2.x &3.x兼容,并保持其他地方看到的高内存效率来改进它们:

代码语言:javascript
运行
复制
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没有那么灵活,因为迭代器必须发出Unicode字符串(而requestsbytes),而2.x版本的for row in csv.reader(r.iter_lines()):-is则更Pythonic (更短、更容易阅读)。无论如何,请注意,上面的2.x/3.x解决方案无法处理OP描述的情况,即在读取的数据中未引用NEWLINE。

对于OP中关于下载(与处理)实际CSV文件有关的部分,下面是另一个脚本,它与2.x &3.x兼容、最小、可读性和内存效率:

代码语言:javascript
运行
复制
import os
import requests

CSV_URL = 'http://web.cs.wpi.edu/~cs1004/a16/Resources/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())
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35371043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档