TalorData SERP API helps you retrieve structured Google Finance SERP data through a Python workflow for market monitoring, financial data enrichment, watchlist tracking, investment research, AI applications, and financial analytics. The workflow extracts key result fields, including stock names, tickers, prices, and market movements, so you can use the data in market monitoring dashboards, internal research tools, AI agents, data pipelines, and automation workflows.
These examples are provided for demonstration purposes only and do not constitute financial advice.
- Step 1: Install prerequisite libraries
- Step 2: Build the core structure
- Step 3: Create a response parsing logic
- Complete code sample
To run this tool, you need Python 3.11 or newer and a TalorData SERP token.
Get your API key:Sign up at TalorData and get your API key from the dashboard.
In your terminal, install the project dependencies:
python -m pip install poetry==1.8.2
poetry installIf you only want to run the standalone code sample from this README, install the HTTP client library:
pip install httpxYou also need a TalorData SERP API token. The packaged CLI reads it from the TALORDATA_SERP_API_TOKEN environment variable, or you can pass it directly in code.
Set your TalorData token . Choose the command for your terminal.
On Windows Command Prompt:
set TALORDATA_SERP_API_TOKEN=<your_talordata_serp_token>
echo %TALORDATA_SERP_API_TOKEN%On Windows PowerShell:
$env:TALORDATA_SERP_API_TOKEN="<your_talordata_serp_token>"
$env:TALORDATA_SERP_API_TOKENNext, let's define the general logic for the finance data collector. We will create functionality for building Google Finance SERP requests, sending each query to TalorData, collecting the structured response, and saving the extracted data as a JSON file.
The TalorData Google Finance request payload uses the google_finance engine and a q value such as GOOGL:NASDAQ:
def build_google_finance_payload(query):
return {
"engine": "google_finance",
"q": query,
"json": "2",
"output_format": "json",
"google_domain": "google.com",
"hl": "en",
}Supported Google Finance parameters in this project are q, google_domain, hl, device, and no_cache. The json=2 and output_format=json values keep the response structured for the parsing logic below.
Now we can send the request. TalorData expects a form-encoded POST request with a Bearer token:
import httpx
TALORDATA_ENDPOINT = "https://serpapi.talordata.net/serp/v1/request"
async def get_finance_response(query, token):
payload = build_google_finance_payload(query)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/x-www-form-urlencoded",
}
async with httpx.AsyncClient(timeout=30) as client:
response = await client.post(
TALORDATA_ENDPOINT,
headers=headers,
data=payload,
)
response.raise_for_status()
return response.json()For the next step, we will create a function that accepts a TalorData response object and returns a smaller object containing the finance information we need:
def extract_finance_information(response):
# Put response extraction here.
listing = {}
return listingSince we can now get the structured Google Finance response and have a function to hold the extraction logic, we can combine both of those into one:
async def extract_finance_data_from_queries(queries, token):
constructed_finance_results = []
for query in queries:
response = await get_finance_response(query, token)
finance = extract_finance_information(response)
constructed_finance_results.append({
"query": query,
"data": finance,
})
return constructed_finance_resultsThis function takes an array of Google Finance queries and returns extracted financial data for each one.
Last but not least, we need a function that takes this data and saves it as a file:
import json
def save_results(results, filepath):
with open(filepath, "w", encoding="utf-8") as file:
json.dump(results, file, ensure_ascii=False, indent=2)
returnTo wrap this up, create a simple main() function that invokes what we have built so far:
import asyncio
import os
async def main():
results_file = "data.json"
token = os.environ["TALORDATA_SERP_API_TOKEN"]
queries = [
"GOOGL:NASDAQ",
"AAPL:NASDAQ",
".INX:INDEXSP",
]
constructed_finance_results = await extract_finance_data_from_queries(queries, token)
save_results(constructed_finance_results, results_file)
if __name__ == "__main__":
asyncio.run(main())The packaged CLI sends the same TalorData request contract:
poetry run talordata-google-finance-serp --query "GOOGL:NASDAQ" --output finance_items.jsonTo export CSV instead, run:
poetry run talordata-google-finance-serp --query "GOOGL:NASDAQ" --output finance_items.csv --format csvAfter running the command, the terminal output should look similar to this:
We have successfully built the core of the application. Now, let's move on to extracting specific data from the TalorData Google Finance response.
First on the list is the pricing data. In a successful quote-shaped Google Finance response, TalorData returns the primary quote details in the summary object. The latest price is usually available under summary.market.price.
The following helper reads the price from the response summary:
def get_price(summary):
market = summary.get("market") or {}
return summary.get("price") or market.get("price")Another important piece of information is the price movement. TalorData keeps this data in summary.market.price_movement, including the value, percentage, and movement direction.
Now we can extract and format the percentage change:
def get_change_percent(summary):
market = summary.get("market") or {}
movement = market.get("price_movement") or {}
percentage = movement.get("percentage")
if percentage is None:
return None
text = str(percentage)
return text if text.endswith("%") else f"{text}%"For the last piece of information, we need the name of the stock. TalorData commonly returns it as summary.title or summary.name.
The final step is to put this into a function:
def get_name(summary):
return summary.get("title") or summary.get("name")Having all of these functions for financial data extraction, we just need to add them to the place we designated earlier:
def extract_finance_information(response):
summary = response.get("summary") or {}
listing = {
"name": get_name(summary),
"price": get_price(summary),
"change_percent": get_change_percent(summary),
}
return listingA generated CSV preview looks like this:
import asyncio
import json
import os
from collections.abc import Mapping
from typing import Any
import httpx
TALORDATA_ENDPOINT = "https://serpapi.talordata.net/serp/v1/request"
def build_google_finance_payload(query: str) -> dict[str, str]:
return {
"engine": "google_finance",
"q": query,
"json": "2",
"output_format": "json",
"google_domain": "google.com",
"hl": "en",
}
async def get_finance_response(query: str, token: str) -> Mapping[str, Any]:
payload = build_google_finance_payload(query)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/x-www-form-urlencoded",
}
async with httpx.AsyncClient(timeout=30) as client:
response = await client.post(
TALORDATA_ENDPOINT,
headers=headers,
data=payload,
)
response.raise_for_status()
return response.json()
def unwrap_response(value: Any) -> Mapping[str, Any]:
if not isinstance(value, Mapping):
return {}
nested_json = value.get("json")
if isinstance(nested_json, Mapping):
return unwrap_response(nested_json)
if isinstance(nested_json, str) and nested_json.strip():
try:
return unwrap_response(json.loads(nested_json))
except ValueError:
pass
for key in ("result", "data", "response"):
nested = value.get(key)
if isinstance(nested, Mapping):
unwrapped = unwrap_response(nested)
if unwrapped:
return unwrapped
return value
def get_price(summary: Mapping[str, Any]) -> str | None:
market = summary.get("market")
market = market if isinstance(market, Mapping) else {}
price = summary.get("price") or market.get("price")
return str(price) if price is not None else None
def get_change_percent(summary: Mapping[str, Any]) -> str | None:
market = summary.get("market")
market = market if isinstance(market, Mapping) else {}
movement = market.get("price_movement")
movement = movement if isinstance(movement, Mapping) else {}
percentage = movement.get("percentage")
if percentage is None:
return None
text = str(percentage)
return text if text.endswith("%") else f"{text}%"
def get_name(summary: Mapping[str, Any]) -> str | None:
name = summary.get("title") or summary.get("name")
return str(name) if name is not None else None
def extract_finance_information(response: Mapping[str, Any]) -> dict[str, str | None]:
data = unwrap_response(response)
summary = data.get("summary")
summary = summary if isinstance(summary, Mapping) else {}
stock = summary.get("stock")
ticker, exchange = (None, None)
if isinstance(stock, str) and ":" in stock:
ticker, exchange = stock.split(":", 1)
market = summary.get("market")
market = market if isinstance(market, Mapping) else {}
movement = market.get("price_movement")
movement = movement if isinstance(movement, Mapping) else {}
return {
"name": get_name(summary),
"ticker": ticker,
"exchange": exchange,
"price": get_price(summary),
"change": str(movement.get("value")) if movement.get("value") is not None else None,
"change_percent": get_change_percent(summary),
"currency": str(summary.get("currency")) if summary.get("currency") is not None else None,
"market_status": str(market.get("trading")) if market.get("trading") is not None else None,
}
async def extract_finance_data_from_queries(queries: list[str], token: str) -> list[dict[str, Any]]:
constructed_finance_results = []
for query in queries:
response = await get_finance_response(query, token)
finance = extract_finance_information(response)
constructed_finance_results.append({
"query": query,
"data": finance,
})
return constructed_finance_results
def save_results(results: list[dict[str, Any]], filepath: str) -> None:
with open(filepath, "w", encoding="utf-8") as file:
json.dump(results, file, ensure_ascii=False, indent=2)
async def main() -> None:
results_file = "data.json"
token = os.environ["TALORDATA_SERP_API_TOKEN"]
queries = [
"GOOGL:NASDAQ",
"AAPL:NASDAQ",
".INX:INDEXSP",
]
constructed_finance_results = await extract_finance_data_from_queries(queries, token)
save_results(constructed_finance_results, results_file)
if __name__ == "__main__":
asyncio.run(main())The repository CLI implements the same flow and can also write the raw TalorData response for debugging:
poetry run talordata-google-finance-serp \
--query "GOOGL:NASDAQ" \
--output finance_items.csv \
--format csv \
--debug-response raw-response.jsonExplore TalorData SERP API integrations and use cases:






