scrapy 如何从雅虎财经获取最大历史价格数据?

aydmsdu9  于 2023-02-04  发布在  其他
关注(0)|答案(6)|浏览(215)

我想从雅虎财经用scrapy得到最大历史价格数据。
以下是Facebook的Facebook Max历史价格数据的网址。

https://query1.finance.yahoo.com/v7/finance/download/FNMA?period1=221115600&period2=1508472000&interval=1d&events=history&crumb=1qRuQKELxmM

为了编写一个股票价格网络爬虫,有两个问题我无法解决。
1.如何得到参数周期1?
你可以在网页中手工获取,只需点击max。
如何用python代码获取参数?
不同的股票有不同的期间值。

2.如何自动创建参数crumb=1qRuQKELxmM,不同的股票有不同的crumb值?
这里是我的股票最大历史数据与scrappy框架。

import scrapy

class TestSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["finance.yahoo.com"]

    def __init__(self, *args, **kw):
        self.timeout = 10

    def start_requests(self):
        stockName =  get-it and ommit the codes 
        for stock in stockName:
            period1 =  how to fill it
            crumb = how to fill it
            per_stock_max_data = "https://query1.finance.yahoo.com/v7/finance\
                  download/"+stock+"?period1="+period1+"&period2=1508472000&\
                  interval=1d&events=history&"+"crumb="crumb
            yield scrapy.Request(per_stock_max_data,callback=self.parse)

    def parse(self, response):
        content = response.body
        target = response.url
        #do something

如何在我的网页涂鸦框架中填补上面的空白?

hyrbngr7

hyrbngr71#

据我所知,你想下载所有可能的数据为一个特定的股票代码。所以要做到这一点,你实际上不需要提供period1参数,如果你提供0的地方period1然后雅虎API把作为默认的最早的日期。
要使用您在问题中显示的方式下载报价,很遗憾,我们必须处理Cookie。我会让自己提供解决方案,而不使用Scrapy,只有股票代码本身是必需的:

def get_yahoo_ticker_data(ticker):
    res = requests.get('https://finance.yahoo.com/quote/' + ticker + '/history')
    yahoo_cookie = res.cookies['B']
    yahoo_crumb = None
    pattern = re.compile('.*"CrumbStore":\{"crumb":"(?P<crumb>[^"]+)"\}')
    for line in res.text.splitlines():
        m = pattern.match(line)
        if m is not None:
            yahoo_crumb = m.groupdict()['crumb']
    cookie_tuple = yahoo_cookie, yahoo_crumb

    current_date = int(time.time())
    url_kwargs = {'symbol': ticker, 'timestamp_end': current_date,
        'crumb': cookie_tuple[1]}
    url_price = 'https://query1.finance.yahoo.com/v7/finance/download/' \
                '{symbol}?period1=0&period2={timestamp_end}&interval=1d&events=history' \
                '&crumb={crumb}'.format(**url_kwargs)

    response = requests.get(url_price, cookies={'B': cookie_tuple[0]})

    return pd.read_csv(StringIO(response.text), parse_dates=['Date'])

如果您确实需要最早的日期,那么您可以使用上面的代码并从响应中提取第一个日期。

get_yahoo_ticker_data(ticker='AAPL')

我知道网页抓取不是一个有效的选择,但它是我们唯一的选择,因为雅虎已经退役了所有的API。你可能会找到一些第三方的解决方案,但他们都在源代码中使用抓取,他们添加了一些额外的锅炉板代码,降低了整体性能。

a0x5cqrl

a0x5cqrl2#

安装panda数据读取器后:

pip install pandas-datareader

您可以使用此代码查询股票价格:

import pandas_datareader as pdr
from datetime import datetime

appl = pdr.get_data_yahoo(symbols='AAPL', start=datetime(2000, 1, 1), end=datetime(2012, 1, 1))
print(appl['Adj Close'])
34gzjxbg

34gzjxbg3#

如果你想要的是整个历史记录,你并不需要计算最大日期,使用一个合理的旧日期(在下面的例子1900/01/01)。例如,让我们假设你对FB的股票感兴趣,那么这应该工作

import scrapy
import time

class FinanceSpider(scrapy.Spider):
    name = "finance"
    allowed_domains = ["finance.yahoo.com"]
    start_urls = ['https://finance.yahoo.com/quote/FB']

    def parse(self, response):
        crumb = response.css('script').re_first('user":{"crumb":"(.*?)"').decode('unicode_escape')
        url = ("https://query1.finance.yahoo.com/v7/finance/download/FB" +
               "?period1=-2208988800&period2=" + str(int(time.time())) + "&interval=1d&events=history&" +
               "crumb={}".format(crumb))
        return scrapy.Request(url, callback=self.parse_csv)

    def parse_csv(self, response):
        lines = response.body.strip().split('\n')
        print(lines[0])
        print(lines[1])
        print(lines[-1])
6psbrbz9

6psbrbz94#

  1. period 1和period 2都是“自纪元以来的秒数”值,你可以使用datetime.datetime.fromtimestamp(dt)int(dt.timestamp())在python时间戳和这些值之间进行转换,但是正如其他人已经提到的,你不需要为这些参数指定确切的数字,你可以为所有股票的period 1使用零,为period 2使用2000000000。
    1.重要的是,相同的“crumb”值在一段时间内(大约1周)对下载所有股票都有效,所以不要在每次下载请求之前都获得一个新的“crumb”,而应该缓存它,只有在收到“未经授权”的响应时才更新;你的下载速度会快两倍。获取crumb值的最简单方法是请求Yahoo主页(https://finance.yahoo.com/)并在那里找到“user”:{“crumb”:“substring。
7gcisfzg

7gcisfzg5#

如果你只是把0放在周期1的位置,它应该会工作,因为间隔将是时间的开始到你刚刚点击的时间。
第二个周期你可以用一个很大的整数,比如1900000000,它只取在那个日期之前发生的所有事情。

lyr7nygr

lyr7nygr6#

遇到此线程并希望添加另一个选项:Python yfinance包。Ticker API有一个历史方法,通过该方法可以将时间段指定为'max',以便返回全部可用资产数据。示例:

import yfinance as yf

spy = yf.Ticker('SPY').history(
    period='max',
    interval='1d'
)

yfinance包使用pandas包,并将spy作为DataFrame对象返回,如下所示:

Open        High  ...  Stock Splits  Capital Gains
Date                                               ...                             
1993-01-29 00:00:00-05:00   25.236177   25.236177  ...           0.0            0.0
1993-02-01 00:00:00-05:00   25.236163   25.397589  ...           0.0            0.0
1993-02-02 00:00:00-05:00   25.379641   25.469322  ...           0.0            0.0
1993-02-03 00:00:00-05:00   25.487262   25.738368  ...           0.0            0.0
1993-02-04 00:00:00-05:00   25.810116   25.881861  ...           0.0            0.0
...                               ...         ...  ...           ...            ...
2023-01-24 00:00:00-05:00  398.880005  401.149994  ...           0.0            0.0
2023-01-25 00:00:00-05:00  395.950012  400.700012  ...           0.0            0.0
2023-01-26 00:00:00-05:00  403.130005  404.920013  ...           0.0            0.0
2023-01-27 00:00:00-05:00  403.660004  408.160004  ...           0.0            0.0
2023-01-30 00:00:00-05:00  402.799988  405.119995  ...           0.0            0.0

[7555 rows x 8 columns]

在写这篇文章的时候(2023年1月30日),这代表了雅虎财经上的完整的每日SPY数据集。或者,period参数的值为None也会产生相同的结果。值得注意的是,省略period的值将使用默认的"1mo"值。

注意:查看Yfinance的源代码可以发现,“max”或None的周期会导致-2208994789(Unix时间为1900)的值被用作开始日期。

相关问题