Google Finance API Is Deprecated: How to Get Financial Data Now
Websites

Nerijus Kriaučiūnas
Key Takeaways
-
Google Finance API was a helpful tool to fetch finance data and was discontinued in 2011.
-
The Finance API was replaced by the =GOOGLEFINANCE function in Google Sheets, but it lacks the accuracy and reliability of the API.
-
Various extensions somewhat improve the market data reliability in spreadsheets, but using a web scraper still has advantages.
-
Scraping public data from Google Finance is generally legal, but your web scraper might face restrictions.
The Google Finance API was killed off a good decade ago, and there is still no comparable solution from Google. While user-friendly, Google Sheets integration lacks the crucial depth and accuracy needed for serious financial analysis or investing.
If the goal was to make financial data from Google more accessible, the result is almost the opposite. Getting accurate real-time stock data might require you to learn basic coding and start a web scraping project for yourself.
The Google Finance API (Application Programming Interface) was a widely used tool for gathering real-time financial data. It allowed developers to integrate Google’s finance database into their scripts, applications, and websites, providing a source of accurate financial data for traders and researchers.
Google Finance API included various financial metrics, currency and exchange rate data, historical and real-time market data, and much more. Despite its widely accepted utility and the fact that Google still supports other APIs, such as the Maps API , the Google Finance API was discontinued in 2011.
As with most projects killed by Google, the exact reasons aren’t publicly known. It is speculated that the Google Finance API was discontinued due to a broader strategic shift in pushing users away from data APIs towards more consumer-facing solutions. Many Google APIs didn’t attract enough developers to create an ecosystem for less tech-savvy users. So, in the case of Google Finance API, users were led to Google Sheets integration, which, while more convenient, provides only some of the functionalities of the Finance API.
Using the GOOGLEFINANCE Formula in Google Sheets
The closest alternative to a Google Finance API that Google itself offers is the Google Sheets GOOGLEFINANCE function. It allows users to fetch historical and current stock market data straight into their Google Sheets. The syntax is as follows:
=GOOGLEFINANCE(ticker, [attribute], [start_date], [end_date|num_days], [interval])
- Ticker - It's best to use an exchange abbreviation followed by the stock to avoid confusion, such as NASDAQ:AAPL or LON:BRBY. If no exchange is specified, the formula will default to the main listing.
- Attribute - Specifies what is fetched about the ticker from Google Finance data. If nothing is specified, 'price' will be used by default. Some of the popular ones are 'high', 'priceopen', and 'marketcap'.
- Start_date - Required when fetching historical data to specify the period. If no end date is specified, a single day is used. A minus value used with TODAY can count the specified number of past days.
- End_date|num_days - Specifies the end date of a historical data period.
- Interval - The data can be specified daily by entering 1 or weekly by entering 7. Other values are not allowed.
For example, the below formula will show the opening price of Apple stock for the past week, fetching new data every day.
=GOOGLEFINANCE("NASDAQ:AAPl","price",TODAY()-7,TODAY(),1)
latest Apple Stock Price | |
---|---|
Date | Close |
7/14/2025 16:00:00 | 208.62 |
7/15/2025 16:00:00 | 209.11 |
7/16/2025 16:00:00 | 210.16 |
7/17/2025 16:00:00 | 210.02 |
7/18/2025 16:00:00 | 211.18 |
With Gemini integration, you can simply ask it to generate the needed stock market data table for you. However, the AI is prone to mistakes when providing real-time stock data, so it's better to learn these functions yourself.
The easiest way is to simply skip the attribute and period specification, so the function would return you the current price by default.
=GOOGLEFINANCE("AAPL", "price")
Besides, stock data Google Finance integration to Sheets can also display currency data. The syntax is similar, but instead of the exchange, you must write 'CURRENCY': followed by two currency codes, like this: 'USDGBP'
=GOOGLEFINANCE("CURRENCY:USDGBP","price", TODAY()-7, TODAY(),1)
USD to GBP Rates | |
---|---|
Date | Close |
7/14/2025 23:58:00 | 0.74471 |
7/15/2025 23:58:00 | 0.74664 |
7/16/2025 23:58:00 | 0.7456899 |
7/17/2025 23:58:00 | 0.7445 |
7/18/2025 23:58:00 | 0.745600954 |
Combined with various other Google Sheets capabilities, the =GOOGLEFINANCE function is quite a powerful tool for teams to integrate market data into their workflows. However, professional traders or financial analysts do not rely on the =GOOGLEFINANCE formula as they used to do with the Google Finance API.
- Delayed updates. Finance data in Sheets is delayed by at least 20 minutes.
- Not all futures are supported. Only the major popular stock options and mutual funds are included. There's also no list of what's included, so you often have to guess.
- Errors when working with large datasets. Users have reported that Sheets are prone to returning errors when pulling large volumes of real-time data needed for market trend analysis.
- Time-consuming. Managing Google Sheets just to pull data might get tedious after a while.
How to Pull Google Finance Data into Excel or Sheets
The STOCKHISTORY function in Microsoft Excel allows pulling stock prices in a similar way that =GOOGLEFINANCE allows doing it in Google Sheets. Unfortunately, the data you'll get there will be similarly limited.
Finance data in Google and Microsoft Excel Sheets can be enhanced by utilizing various extensions.
- Excel Price Feed is an extension that adds lots of new Excel functions and can pull live historical data from various sources.
- YHFINANCE extension will allow you to pull Yahoo Finance data similarly to your =GOOGLEFINANCE function in Sheets and Excel.
- Wisesheets extension expands the list of available currencies and futures, as well as adds various visualization and comparison functionalities.
While these extensions add some much-needed data accuracy, they are far from what an official Google Finance API offers. Since there is no official Google Finance API to use, the next best thing is to build a web scraper to collect the data from Google yourself.
How to Scrape Google Finance Data in 2025
Building your own web scraper can solve the problems that the lack of the Google Finance API created. Even a simple web scraper can get the needed market data with almost no delay after you run the script and access all the futures found on google.com/finance.
Scraping stock market data is generally legal since information such as prices, indices, or trade volumes is considered publicly available data not subject to copyright protection. Yet, web scraping is against Google's terms of service, and your IP address might get restricted.
As long as you don't use the collected sock market data commercially or redistribute it for profit, legal action against you is unlikely. If you have any doubts, consider consulting with a lawyer. Otherwise, using proxies for stock market data will protect you against restrictions.
Besides proxies, our example Python web scraper will use a headless browser, Selenium, and a few additional libraries - Seleniumwire, Pandas, and WebDriverManager. Start with:
pip install selenium-wire pandas webdrivermanager blinker==1.6.2
from seleniumwire import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import pandas as pd
import time
# Proxy configuration (uncomment and replace with your proxy details)
# proxy_options = {
# 'proxy': {
# 'http': 'http://username:password@proxy-server:port',
# 'https': 'https://username:password@proxy-server:port',
# 'no_proxy': 'localhost,127.0.0.1'
# }
# }
# Alternative proxy configuration format (for different proxy types)
# proxy_options = {
# 'proxy': {
# 'http': 'http://proxy-server:port',
# 'https': 'https://proxy-server:port'
# }
# }
# For SOCKS proxies
# proxy_options = {
# 'proxy': {
# 'http': 'socks5://proxy-server:port',
# 'https': 'socks5://proxy-server:port'
# }
# }
# Setup Chrome options
options = webdriver.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument(
'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
# Additional options for better proxy compatibility
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--disable-web-security')
options.add_argument('--allow-running-insecure-content')
# Initialize driver with selenium-wire (supports proxies)
# Without proxy:
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options
)
# With proxy (uncomment the lines below and comment the lines above):
# driver = webdriver.Chrome(
# service=Service(ChromeDriverManager().install()),
# options=options,
# seleniumwire_options=proxy_options
# )
try:
# Navigate to the page
print("Navigating to the page...")
driver.get("https://www.google.com/finance/")
time.sleep(3) # Give page time to load
# Handle cookie consent dialog
print("Checking for cookie consent dialog...")
try:
# Wait for cookie dialog to appear and try different accept button selectors
# Based on the actual HTML structure provided
cookie_selectors = [
'//button[@jsname="b3VHJd"]', # Accept all button jsname
'//button[@aria-label="Accept all"]',
'//button[contains(@class, "UywwFc-LgbsSe") and contains(., "Accept all")]',
'//span[text()="Accept all"]/parent::button',
'//span[@jsname="V67aGc" and text()="Accept all"]/parent::button',
'//button[contains(text(), "Accept all")]',
'//button[contains(text(), "I agree")]',
'//button[@id="L2AGLb"]' # Fallback common Google accept button ID
]
cookie_accepted = False
for selector in cookie_selectors:
try:
accept_button = WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, selector))
)
accept_button.click()
print(f"Clicked accept cookies button using selector: {selector}")
cookie_accepted = True
time.sleep(3) # Wait for dialog to close and page to load
break
except:
continue
if not cookie_accepted:
print("No cookie dialog found or couldn't click accept button")
except Exception as e:
print(f"Cookie dialog handling failed: {e}")
# Continue anyway, sometimes the dialog doesn't appear
# Find the search box and enter "AAPL"
print("Searching for AAPL...")
try:
# First, try to click on the search container to activate it
print("Trying to activate search box...")
search_container_selectors = [
'//div[@class="M52nVb ytPNkd"]',
'//div[@jscontroller="XijuNc"]',
'//div[@data-placeholder="Search for stocks, ETFs & more"]'
]
search_container = None
for selector in search_container_selectors:
try:
search_container = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, selector))
)
search_container.click()
print(f"Clicked search container using selector: {selector}")
time.sleep(2) # Wait for search box to activate
break
except:
continue
# Now try to find the actual input
search_selectors = [
'//input[@jsname="dSO9oc"]',
'//input[contains(@class, "Ax4B8") and not(@disabled)]',
'//input[@role="combobox" and not(@disabled)]'
]
search_box = None
for selector in search_selectors:
try:
search_box = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, selector))
)
print(f"Found search input using selector: {selector}")
break
except:
continue
if search_box:
print("Trying standard Selenium approach...")
try:
# Focus and clear the input
search_box.click()
time.sleep(1)
search_box.clear()
time.sleep(1)
# Try typing character by character
search_term = "AAPL"
for char in search_term:
search_box.send_keys(char)
time.sleep(0.2) # Small delay between characters
print(f"Typed: {search_term}")
time.sleep(2) # Wait for autocomplete
search_box.send_keys(Keys.RETURN)
print("Pressed Enter")
time.sleep(3) # Wait for search results
# Check if we're on a stock page now
current_url = driver.current_url
if "AAPL" in current_url or "quote" in current_url:
print("Successfully navigated to stock page")
else:
raise Exception("Search didn't navigate to expected page")
except Exception as selenium_error:
print(f"Selenium approach failed: {selenium_error}")
raise selenium_error
else:
raise Exception("Could not find search input")
except Exception as search_error:
print(f"Search approach failed: {search_error}")
# Fallback 1: Use JavaScript to interact with the search
print("Trying JavaScript approach...")
try:
js_script = """
// Find and focus the search input
var input = document.querySelector('input[jsname="dSO9oc"]');
if (!input) {
input = document.querySelector('input.Ax4B8:not([disabled])');
}
if (input) {
// Clear and focus
input.value = '';
input.focus();
// Set the value
input.value = 'AAPL';
// Trigger events that Google expects
var events = ['focus', 'input', 'change'];
events.forEach(function(eventType) {
var event = new Event(eventType, { bubbles: true, cancelable: true });
input.dispatchEvent(event);
});
// Wait a moment then trigger Enter
setTimeout(function() {
var enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
which: 13,
bubbles: true,
cancelable: true
});
input.dispatchEvent(enterEvent);
}, 500);
return 'success - value set to: ' + input.value;
} else {
return 'failed - input not found';
}
"""
result = driver.execute_script(js_script)
print(f"JavaScript result: {result}")
if 'success' in result:
time.sleep(5) # Wait for navigation
current_url = driver.current_url
if "AAPL" in current_url or "quote" in current_url:
print("JavaScript approach successful")
else:
raise Exception("JavaScript didn't navigate to expected page")
else:
raise Exception("JavaScript approach failed")
except Exception as js_error:
print(f"JavaScript approach failed: {js_error}")
# Fallback 2: Direct navigation
print("Using direct navigation fallback...")
driver.get("https://www.google.com/finance/quote/AAPL:NASDAQ")
time.sleep(5)
# Wait for the Apple Inc. stock page to load
print("Waiting for Apple Inc. stock page to load...")
time.sleep(5)
# Extract the current price using multiple fallback selectors
print("Extracting current price...")
price = None
# Try multiple selectors in case Google changes their layout
selectors = [
'//div[@class="YMlKec fxKbKc"]',
'//div[contains(@class, "YMlKec")]',
'//div[@data-last-price]',
'//span[@class="IsqQVc NprOob wT3VGc"]',
'//div[contains(@class, "kf1m0")]'
]
for selector in selectors:
try:
price_element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, selector))
)
price = price_element.text
print(f"Found price using selector: {selector}")
break
except:
continue
if not price:
raise Exception("Could not find price element with any of the selectors")
# Save the price to a CSV file
print(f"Current price of AAPL: {price}")
df = pd.DataFrame({"Stock": ["AAPL"], "Price": [price]})
df.to_csv("apple_stock_price.csv", index=False)
print("Saved the current price to apple_stock_price.csv")
except Exception as e:
print(f"An error occurred: {str(e)}")
driver.save_screenshot("error_screenshot.png")
print("Screenshot saved as error_screenshot.png")
finally:
# Close the browser
input("Press Enter to close the browser...")
driver.quit()
Note that here we are using the text in the search bar to locate it, and a div class to find the XPath to find the stock price. Both might change in case Google updates the page, so you might need to inspect the page manually.
Conclusion
Refer to our general Python web scraping guide for a more detailed tutorial on how to get started with such projects. Once you've mastered building and maintaining a Python scraper, it can become the main source of professional market data and an alternative to the Google Finance API.