【问题标题】:Using Python Requests to download CSV file after authentication验证后使用 Python 请求下载 CSV 文件
【发布时间】:2018-07-25 14:39:13
【问题描述】:

我正在尝试以编程方式从网络下载“.csv”文件。我收到带有以下代码的 200 响应。

import requests
url = 'http://eoddata.com/data/filedownload.aspx?e=NYSE&sd=20180722&ed=20180722&d=5&k=xh2mnktdc4&o=d&ea=1&p=0'
user, password = '..', '..'
resp = requests.get(url, auth=(user, password))

在浏览器中提交此 URL 时,“.csv”文件会自动下载。我试图让我的应用程序在本地存储文件。我不知道文件的结束位置,所以我很难保存它。

我添加了 HTTP Live Headers 扩展,它给了我这个:

GET /data/filedownload.aspx?e=AMEX&sd=20180719&ed=20180719&d=5&k=n4vic5se64&o=d&ea=1&p=0 HTTP/1.1
Host: eoddata.com
Accept: text/css,*/*;q=0.1
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: ASP.NET_SessionId=drbcwljllaf3xdwdlvqzfvl1;EODDataAdmin=01438A3826CBEEC6085BF7B27AEB1BE6AF337FFBF3E3E33AA1D882D39FB92555E8370DD45631B3F8CAD5289C5C46DB28C99B44DC8253A78D659EB165ADC55A1D6E4C20FA81051908E6BE82143EA5398662779546BE4C31C6F32833C5558F23C9A30D0CA16A703CB939FC6D77A0FB0CB017DDEEA832A1A0CC228B61777295C58CA52AF78B472B9D2FC19E78770DEBD346E9B05F02C65F96EE22C3E55B083FC4A1311FA12B223CC2899D6166E1284AD95E
DNT: 1
Referer: http://eoddata.com/download.aspx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

HTTP/1.1 200 OK
Cache-Control: private
content-disposition: attachment;filename="AMEX_20180719.csv"
Content-Length: 93840
Content-Type: text/plain
Date: Wed, 25 Jul 2018 13:54:31 GMT
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

非常感谢您在保存预期文件方面的任何帮助。

编辑: 我想在标题响应中指出这一行:content-disposition: attachment;filename="AMEX_20180719.csv" 这有什么不同吗?

【问题讨论】:

  • 你能不能通过使用流作为参数来获取。 resp = requests.get(url, auth=(user, password), stream=True) 然后使用 iter_content() 下载块
  • 我认为您的建议与@Sam 相同。如果是这样,它没有工作。内容处置是一个附件,你知道这是否有问题吗?

标签: python python-3.x authentication python-requests


【解决方案1】:

试试这个:

import requests, urllib
from tqdm import tqdm

def download_file(url):

    filename = "FILENAME.csv"
    print("Downloading %s ..." % filename)

    with open(filename, "wb") as handle:
        for data in tqdm(response.iter_content()):
            handle.write(data)

    print("Download complete for %s!" % filename)

username = "USERNAME"
password = "PASSWORD"

data_credentials = {'user_id': username, 'password': password}
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}

login_url = "https://mywebsite.com/login/"

requests_session = requests.Session() # create a requests Session

response = requests_session.post(login_url, headers=headers, data=data_credentials) # log in to the requests Session so that you can reuse it

download_url = "http://www.downloadmyfile.com/something.csv"

response = requests_session.get(download_url, timeout=(15,15))

download_file(response.url) # run function to download file

【讨论】:

  • 我会试试这个,但我不知道下载 url 端点。我是否在 HTTP Live Headers 块中错过了它?
  • 我拥有的 URL 显然是问题所在。我不知道如何从我的问题中的 HTTP Live Headers 响应中解析到“AMEX_20180719.csv”的直接链接。
【解决方案2】:

由于您的请求似乎正在通过,您剩下要做的就是实际下载文件。以下是我通常使用请求下载文件的方式:

import requests

def download_file(url, user, password, file_path):
    with requests.get(url, stream = True, auth = (user, password)) as response:
        with open(file_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size = 1024):
                f.write(chunk)

在这种情况下,不要忘记以 .csv 结束 file_path。

【讨论】:

  • 谢谢。此 URL 的响应中似乎没有内容。 'for chunk in ...' 什么也不打印。
  • 有趣。有时我无法通过直接链接下载,因为该站点希望请求中存在某些标头。查看您问题中的信息,也许该站点希望将 Referer 标头正确设置为 http://eoddata.com/download.aspx?试一试也无妨。您可以通过在 requests.get() 调用中添加 headers 关键字参数来向请求添加标头,传入标头名称、标头值对的字典。也可能需要 cookie。
猜你喜欢
  • 2016-05-24
  • 2019-01-12
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
相关资源
最近更新 更多