From b73f7d1298f41a64b3906e0084fccdc6b3936055 Mon Sep 17 00:00:00 2001 From: dietmarb <3762263+dietmarb01@users.noreply.github.com> Date: Sun, 5 May 2024 11:51:42 +0200 Subject: [PATCH] patch for TradingView search API change to v3 - Tradingview have changed their search API to "v3". In addition, their Nginx frontend now blocks requests with Origin+Referer other than their own site. - fixes https://github.com/rongardF/tvdatafeed/issues/45 - version bumped to 2.1.0_issue45 - only tested with Python 3.12 Changes in this commit: modified: __init__.py modified: main.py --- tvDatafeed/__init__.py | 2 +- tvDatafeed/main.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tvDatafeed/__init__.py b/tvDatafeed/__init__.py index 737b7b6..7551e56 100644 --- a/tvDatafeed/__init__.py +++ b/tvDatafeed/__init__.py @@ -3,4 +3,4 @@ from .datafeed import TvDatafeedLive from .consumer import Consumer -__version__ = "2.1.0" +__version__ = "2.1.0_issue45" diff --git a/tvDatafeed/main.py b/tvDatafeed/main.py index de77ebc..d7eae9d 100644 --- a/tvDatafeed/main.py +++ b/tvDatafeed/main.py @@ -31,9 +31,10 @@ class Interval(enum.Enum): class TvDatafeed: __sign_in_url = 'https://www.tradingview.com/accounts/signin/' - __search_url = 'https://symbol-search.tradingview.com/symbol_search/?text={}&hl=1&exchange={}&lang=en&type=&domain=production' + __search_url = 'https://symbol-search.tradingview.com/symbol_search/v3/?text={}&hl=1&exchange={}&lang=en&search_type=&domain=production' __ws_headers = json.dumps({"Origin": "https://data.tradingview.com"}) __signin_headers = {'Referer': 'https://www.tradingview.com'} + __search_headers = {'Referer': 'https://www.tradingview.com', 'Origin': 'https://data.tradingview.com'} __ws_timeout = 5 def __init__( @@ -294,11 +295,13 @@ def search_symbol(self, text: str, exchange: str = ''): symbols_list = [] try: - resp = requests.get(url) + # Need Referer _and_ Origin headers, otherwise their Nginx frontend returns 403 :-( + resp = requests.get(url, headers=self.__search_headers, timeout=60) + resp.raise_for_status() - symbols_list = json.loads(resp.text.replace( - '', '').replace('', '')) - except Exception as e: + # As of v3, this returns a dict: {'symbols_remaining':, 'symbols': [...]} + symbols_list = json.loads(resp.text).get('symbols', []) + except Exception as e: # pylint: disable=broad-exception-caught logger.error(e) return symbols_list