import requests import yfinance as yf import urllib.parse # Add this import statement class YFinance: user_agent_key = "User-Agent" user_agent_value = ("Mozilla/5.0 (Windows NT 6.1; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/58.0.3029.110 Safari/537.36") def __init__(self, ticker): self.yahoo_ticker = ticker def __str__(self): return self.yahoo_ticker def _get_yahoo_cookie(self): cookie = None headers = {self.user_agent_key: self.user_agent_value} response = requests.get("https://fc.yahoo.com", headers=headers, allow_redirects=True) if not response.cookies: raise Exception("Failed to obtain Yahoo auth cookie.") cookie = list(response.cookies)[0] return cookie def _get_yahoo_crumb(self, cookie): crumb = None headers = {self.user_agent_key: self.user_agent_value} crumb_response = requests.get( "https://query1.finance.yahoo.com/v1/test/getcrumb", headers=headers, cookies={cookie.name: cookie.value}, allow_redirects=True, ) crumb = crumb_response.text if crumb is None: raise Exception("Failed to retrieve Yahoo crumb.") return crumb def get_history(self, period="max"): # Obtain cookies and crumb for downloading historical data cookie = self._get_yahoo_cookie() crumb = self._get_yahoo_crumb(cookie) # Fetch historical stock data using yfinance stock = yf.Ticker(self.yahoo_ticker) return stock.history(period=period) @property def info(self): cookie = self._get_yahoo_cookie() crumb = self._get_yahoo_crumb(cookie) info = {} ret = {} headers = {self.user_agent_key: self.user_agent_value} yahoo_modules = ("summaryDetail," "financialData," "quoteType," "assetProfile," "indexTrend," "defaultKeyStatistics") url = ("https://query1.finance.yahoo.com/v10/finance/" f"quoteSummary/{self.yahoo_ticker}" f"?modules={urllib.parse.quote_plus(yahoo_modules)}" # Use urllib.parse.quote_plus f"&ssl=true&crumb={urllib.parse.quote_plus(crumb)}") # Use urllib.parse.quote_plus info_response = requests.get(url, headers=headers, cookies={cookie.name: cookie.value}, allow_redirects=True) info = info_response.json() info = info['quoteSummary']['result'][0] for mainKeys in info.keys(): for key in info[mainKeys].keys(): if isinstance(info[mainKeys][key], dict): try: ret[key] = info[mainKeys][key]['raw'] except (KeyError, TypeError): pass else: ret[key] = info[mainKeys][key] return ret