一致地从Yahoo Finance检索Cookie和面包屑以进行历史数据下载

时间:2019-06-21 06:31:39

标签: python cookies yahoo-finance

我正在从事一个涉及从Yahoo Finance下载历史股价数据的项目。此过程中的步骤涉及确定要与URL一起使用以下载数据的正确cookie和面包屑。我目前拥有的代码有时只能工作,即可以毫无问题地检索库存数据,并且在看似随机的迭代中会失败。在整个问题中,我正在下载多只股票的数据。我遇到的问题是检索数据时缺乏一致性。我遇到了一个问题,返回的数据是

b'{\n"finance":{\n"error":{\n"code":"Unauthorized",\n"description":"Invalid cookie"\n}\n}\n}\n

所以,我认为问题出在cookie检索集中。

为了测试该问题,我编写了一个小脚本,尝试通过20次迭代下载相同库存的数据。运行此代码时,通常会有大约18个左右的迭代正常运行,而其他迭代将不工作。每当我执行测试脚本时,发生这种情况的迭代次数都会发生变化。

这是到目前为止我一直在使用的测试代码:

import requests
import time
import re
for k in range(20):
    symbol='AMZN'
    url="https://finance.yahoo.com/quote/%s/?p=%s" % (symbol, symbol)
    r = requests.get(url, timeout=10)
    cookie = r.cookies
    lines = r.content.decode('latin-1').replace('\\', '')
    lines = lines.replace('}', '\n')
    lines = lines.split('\n')
    for l in lines:
        if re.findall(r'CrumbStore', l):
            crumb = l.split(':')[2].strip('"')
    start_date = int(int(time.time())-15*86400)
    end_date = int(time.time())
    url = "https://query1.finance.yahoo.com/v7/finance/download/%s?period1=%s&period2=%s&interval=1d&events=history&crumb=%s" % (symbol, start_date, end_date, crumb)
    response = requests.get(url, cookies=cookie, timeout=10)
    for block in response.iter_content(1024):
        print(block)
        print(k)

我希望它每次都会返回股票价格数据,类似于:

b'Date,Open,High,Low,Close,Adj Close,Volume\n2019-06-06,1737.709961,1760.000000,1726.130005,1754.359985,1754.359985,3689300\n2019-06-07,1763.699951,1806.250000,1759.489990,1804.030029,1804.030029,4808200\n2019-06-10,1822.000000,1884.869995,1818.000000,1860.630005,1860.630005,5371000'

但是,有时会出现错误。有没有更可靠的方法来确保正确下载数据?我知道我可以访问和下载它,但是代码不可靠。

请注意,这类似于尝试通过浏览器直接通过不良的cookie /小块访问数据,例如通过url:

https://query1.finance.yahoo.com/v7/finance/download/AMZN?period1=1559367165&period2=1560663165&interval=1d&events=history&crumb=ODCkS0u002FOZyL

谢谢您的帮助。

2 个答案:

答案 0 :(得分:0)

问题与您的代码无关。它在Yahoo服务器端。我看到这个问题是完全随机的。如果您击中了无效的cookie,那么您将连续获得无效的cookie。我猜循环无法帮助您跳过这个问题。

也许,您一次可以保存一个有效的cookie和面包屑对。您可以加载此对以获取数据。

# Save cookie.
with open('cookie', 'wb') as f:
    pickle.dump(cookie, f)

加载cookie是:

# Load cookie.
with open('cookie', 'rb') as f:
    session.cookies.update(pickle.load(f))

答案 1 :(得分:0)

我恰好遇到了这个问题,试图下载历史数据以获得股票清单。我使用蛮力方法将其修复,对每个请求进行5次迭代,如果请求成功,则退出循环。如果请求有效,则返回的前几个字符为“ Date,Open”。

    String crumb = getCrumb(securityID); // get the crumb

    String yahooQuery = "?period1=" + fromDate + "&period2=" + toDate + 
    "&interval=1d&events=history&crumb=" + crumb;

    String requestURL = 
    "https://query1.finance.yahoo.com/v7/finance/download/" + securityID + 
    yahooQuery;

    PostRequest stockDetail = new PostRequest(requestURL);

    for (int tries = 0; tries < 5; tries++) {

        // Get history CSV file
        stockDetail.send();

        if (stockDetail.getContent().contains("Date,Open")) {
            break;
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
    }