我正在从事一个涉及从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
谢谢您的帮助。
答案 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) {
}
}