Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions yfinance/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import requests as requests
import re
from bs4 import BeautifulSoup
import random
import time

from frozendict import frozendict

Expand Down Expand Up @@ -202,6 +204,11 @@ def _get_proxy(self, proxy):
proxy = {"https": proxy}
return proxy

def get_raw_json(self, url, user_agent_headers=None, params=None, proxy=None, timeout=30):
response = self.get(url, user_agent_headers=user_agent_headers, params=params, proxy=proxy, timeout=timeout)
response.raise_for_status()
return response.json()

def _get_decryption_keys_from_yahoo_js(self, soup):
result = None

Expand Down
40 changes: 33 additions & 7 deletions yfinance/scrapers/quote.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

PRUNE_INFO = True
# PRUNE_INFO = False
_BASIC_URL_ = "https://query1.finance.yahoo.com/v7/finance/quote"


from collections.abc import MutableMapping
Expand Down Expand Up @@ -87,13 +88,16 @@ def __init__(self, data: TickerData, proxy=None):
self._calendar = None

self._already_scraped = False
self._already_scraped_complementary = False
self._already_fetched = False
self._already_fetched_complementary = False

@property
def info(self) -> dict:
if self._info is None:
self._scrape(self.proxy)
self._scrape_complementary(self.proxy)
# self._scrape(self.proxy) # decrypt broken
self._fetch(self.proxy)

self._fetch_complementary(self.proxy)

return self._info

Expand Down Expand Up @@ -236,12 +240,34 @@ def _scrape(self, proxy):
except Exception:
pass

def _scrape_complementary(self, proxy):
if self._already_scraped_complementary:
def _fetch(self, proxy):
if self._already_fetched:
return
self._already_fetched = True

result = self._data.get_raw_json(
_BASIC_URL_, params={"formatted": "true", "lang": "en-US", "symbols": self._data.ticker}, proxy=proxy
)
query1_info = next(
(info for info in result.get("quoteResponse", {}).get("result", []) if info["symbol"] == self._data.ticker),
None,
)
for k, v in query1_info.items():
if isinstance(v, dict) and "raw" in v and "fmt" in v:
query1_info[k] = v["fmt"] if k in {"regularMarketTime", "postMarketTime"} else v["raw"]
elif isinstance(v, str):
query1_info[k] = v.replace("\xa0", " ")
elif isinstance(v, (int, bool)):
query1_info[k] = v
self._info = query1_info

def _fetch_complementary(self, proxy):
if self._already_fetched_complementary:
return
self._already_scraped_complementary = True
self._already_fetched_complementary = True

self._scrape(proxy)
# self._scrape(proxy) # decrypt broken
self._fetch(proxy)
if self._info is None:
return

Expand Down