File indexing completed on 2024-04-28 16:30:15
0001 #!/usr/bin/env python3 0002 # -*- coding: utf-8 -*- 0003 #*************************************************************************** 0004 #* SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr 0005 #* SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr 0006 #* SPDX-License-Identifier: GPL-3.0-or-later 0007 #*************************************************************************** 0008 0009 """ 0010 Created on Thu May 18 22:58:12 2017 0011 @author: c0redumb 0012 """ 0013 0014 # To make print working for Python2/3 0015 from __future__ import print_function 0016 0017 # Use six to import urllib so it is working for Python2/3 0018 from six.moves import urllib 0019 # If you don't want to use six, please comment out the line above 0020 # and use the line below instead (for Python3 only). 0021 #import urllib.request, urllib.parse, urllib.error 0022 0023 import time 0024 import sys 0025 0026 ''' 0027 Starting on May 2017, Yahoo financial has terminated its service on 0028 the well used EOD data download without warning. This is confirmed 0029 by Yahoo employee in forum posts. 0030 Yahoo financial EOD data, however, still works on Yahoo financial pages. 0031 These download links uses a "crumb" for authentication with a cookie "B". 0032 This code is provided to obtain such matching cookie and crumb. 0033 ''' 0034 0035 # Build the cookie handler 0036 cookier = urllib.request.HTTPCookieProcessor() 0037 opener = urllib.request.build_opener(cookier) 0038 urllib.request.install_opener(opener) 0039 0040 # Cookie and corresponding crumb 0041 _cookie = None 0042 _crumb = None 0043 0044 def _get_cookie_crumb(ticker): 0045 ''' 0046 This function perform a query and extract the matching cookie and crumb. 0047 ''' 0048 # Perform a Yahoo financial lookup 0049 url = 'https://finance.yahoo.com/quote/' + ticker 0050 hdr = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)', 0051 'content-type': 'text/html; charset=utf-8'} 0052 req = urllib.request.Request(url, headers=hdr) 0053 f = urllib.request.urlopen(req) 0054 alines = f.read() 0055 alines = alines.decode('utf-8') 0056 0057 # Extract the crumb from the response 0058 global _crumb 0059 cs = alines.find('CrumbStore') 0060 cr = alines.find('crumb', cs + 10) 0061 cl = alines.find(':', cr + 5) 0062 q1 = alines.find('"', cl + 1) 0063 q2 = alines.find('"', q1 + 1) 0064 crumb = alines[q1 + 1:q2] 0065 _crumb = crumb 0066 0067 # Extract the cookie from cookiejar 0068 global cookier, _cookie 0069 for c in cookier.cookiejar: 0070 if c.domain != '.yahoo.com': 0071 continue 0072 if c.name != 'B': 0073 continue 0074 _cookie = c.value 0075 0076 def load_yahoo_quote(ticker, begindate, enddate, interval): 0077 ''' 0078 This function load the corresponding history from Yahoo. 0079 ''' 0080 # Check to make sure that the cookie and crumb has been loaded 0081 global _cookie, _crumb 0082 if _cookie == None or _crumb == None: 0083 _get_cookie_crumb(ticker) 0084 0085 begindate = begindate.replace('-', '') 0086 enddate = enddate.replace('-', '') 0087 0088 # Prepare the parameters and the URL 0089 tb = int(time.mktime((int(begindate[0:4]), int(begindate[4:6]), int(begindate[6:8]), 0, 0, 0, 0, 0, 0))) 0090 te = int(time.mktime((int(enddate[0:4]), int(enddate[4:6]), int(enddate[6:8]), 0, 0, 0, 0, 0, 0))) 0091 if te == tb: 0092 tb = tb -1 0093 0094 param = dict() 0095 param['period1'] = tb 0096 param['period2'] = te 0097 param['interval'] = interval 0098 param['events'] = 'history' 0099 param['crumb'] = _crumb 0100 params = urllib.parse.urlencode(param) 0101 url = 'https://query1.finance.yahoo.com/v7/finance/download/{}?{}'.format(ticker, params) 0102 0103 # Perform the query 0104 # There is no need to enter the cookie here, as it is automatically handled by opener 0105 try: 0106 f = urllib.request.urlopen(url) 0107 alines = f.read().decode('utf-8') 0108 return sorted(alines.split('\n'), reverse=True) 0109 except IOError: 0110 return ["Date,Open,High,Low,Close,Adj Close,Volume"] 0111 0112 0113 for l in load_yahoo_quote(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]): 0114 print(l)