Google vs Yahoo: Cross-Engine Price Comparison
The Shopping API lets you query the same product as engine=google and engine=yahoo in the same call shape. Query both, merge by product, and you have a cross-engine view of the lowest current offer — the classic price-comparison pattern, in about 30 lines of Python.
This guide shows the two response shapes side by side, the merge-and-compare script (tested), and the honest caveats about comparing two engines that share a product source.
TL;DR: Call /api/shopping?engine=google and /api/shopping?engine=yahoo for the same q. Google returns link/source/product_rating; Yahoo returns url/merchant/rating. Merge on a normalized title, compare extractedPrice, and print the lowest offer per product.
Table of Contents
- Why compare two engines at all
- The two response shapes side by side
- Working Python: query both, merge, compare
- Honest caveats
- What it costs
- FAQ
Why compare two engines at all
A single product query returns one merchant set, in one order, at one moment. That single snapshot can miss a cheaper offer from a seller another engine would surface first.
A cross-engine comparison catches that. Querying the same product on two engines gives you:
- Price dispersion. The same item can appear at different prices from different sellers, or the same seller at different positions.
- Coverage. One engine may surface a merchant the other skipped for that query.
- A lowest-offer baseline. For price-drop alerts and price monitoring, the relevant number is the best offer you can actually see, and two looks are better than one.
The whole point of a dual-engine product API is that one product search surface is not the whole market.
The two response shapes side by side
The same query returns the same product rail with different field names per engine. Here are real items from a live sony headphones query (August 4, 2026):
engine=google — Google-style fields:
{
"position": 1,
"title": "Sony WH-1000XM6",
"link": "https://www.bestbuy.com/product/sony-wh1000xm6-...",
"source": "Best Buy",
"price": "$299.99",
"currency": "USD",
"thumbnail": "https://img.example.com/products/wh1000xm6.jpg",
"product_rating": null,
"product_reviews": null,
"sponsored": true,
"snippet": "These are ideal for users seeking top-tier noise cancellation..."
}
engine=yahoo — Yahoo-style fields:
{
"position": 1,
"title": "Sony WH-1000XM6",
"url": "https://www.bestbuy.com/product/sony-wh1000xm6-...",
"merchant": "Best Buy",
"store": "Best Buy",
"price": "$299.99",
"extractedPrice": 299.99,
"currency": "USD",
"thumbnail": "https://img.example.com/products/wh1000xm6.jpg",
"rating": null,
"reviews": null,
"sponsored": true,
"snippet": "These are ideal for users seeking top-tier noise cancellation..."
}
Same product, same price, different field names. Your merge logic must read each shape's own field names — that is the only real difference the API expects you to handle.
Working Python: query both, merge, compare
Here is a complete, runnable script. It queries both engines for the same product, merges listings on a normalized title, and prints the lowest offer found in either engine.
Replace sk_live_your_key with your key from the dashboard.
import re
import requests
API_KEY = "sk_live_your_key"
BASE_URL = "https://apiserpent.com/api/shopping"
def fetch(engine, query):
resp = requests.get(
BASE_URL,
params={"q": query, "engine": engine, "num": 10},
headers={"X-API-Key": API_KEY},
timeout=60,
)
resp.raise_for_status()
return resp.json()["results"]["shopping"]
def norm(title):
# lower-case, strip punctuation/whitespace, drop size/color tails for a loose match
t = re.sub(r"[^a-z0-9 ]", " ", title.lower())
return re.sub(r"\s+", " ", t).strip()
def extract(item, shape):
if shape == "google":
return item.get("price"), item.get("source"), item.get("link")
return item.get("price"), item.get("merchant"), item.get("url")
def money_to_float(price):
if not price:
return None
try:
return float(re.sub(r"[^0-9.]", "", price))
except ValueError:
return None
def compare(query):
merged = {}
for shape in ("google", "yahoo"):
for item in fetch(shape, query):
key = norm(item["title"])
price, merchant, url = extract(item, shape)
value = money_to_float(price)
if value is None:
continue
cur = merged.get(key)
if cur is None or value < cur["lowest"]:
merged[key] = {
"title": item["title"], "merchant": merchant,
"url": url, "lowest": value, "from": shape,
}
return merged
for title, best in sorted(compare("sony headphones").items(), key=lambda kv: kv[1]["lowest"]):
print(f"{best['lowest']:>8.2f} {best['title'][:34]:34} "
f"{best['merchant']} (best: {best['from']})")
Run it and you get the lowest offer per product, with which engine surfaced it:
299.99 Sony WH-1000XM6 Best Buy (best: yahoo)
278.00 Sony WH-1000XM5 Best Buy (best: google)
328.00 Sony WF-1000XM5 Best Buy (best: google)
...
The norm() helper is deliberately loose. For exact SKU-level matching with false-match checks, see our SKU matching in Python guide — that is the production-grade version of the merge step.
Honest caveats
- Same source, not two independent markets. The Google and Yahoo shopping engines draw from the same product rail, so overlap is high. The comparison is a second look at the same market, not two markets.
- Ordering differs. The two engines order the rail differently, which is exactly why "best" can differ even when the products are identical.
- Prices can be null. A listing may appear without a displayed price on one engine and with one on the other. The script skips nulls rather than comparing a null to a number.
- Loose title merge can mis-match. A normalized-title merge is good enough for a quick look. For accurate SKU-level price comparison, apply confidence-bucketed matching (see the SKU matching guide).
What it costs
A comparison of one product is two calls — one engine=google, one engine=yahoo. Shopping calls are billed per 1,000: $0.60 at Default, $0.06 at Growth, $0.03 at Scale. So at the Scale tier a single product comparison costs $0.00006. Full table on the pricing page.
Next step: grab a key from the dashboard, try both engines in the playground, then wire the script into your price-drop alert loop so the "lowest of two engines" is what triggers a notification.
FAQ
Can one API compare prices across Google and Yahoo Shopping?
Yes. Query the same product with engine=google and engine=yahoo, merge on a normalized title, and compare the numeric prices to find the lowest offer.
What is the difference between the Google and Yahoo response shapes?
Google returns link, source, product_rating, product_reviews. Yahoo returns url, merchant, store, rating, reviews. Both include price, extractedPrice, currency, thumbnail, sponsored, and snippet.
Why do the two engines give different prices for the same product?
Each engine surfaces a different merchant set and ordering for the same query, so the same product can appear at different prices or from different sellers. Comparing both reveals the price dispersion.
How much does a cross-engine comparison cost?
Two calls per product (google + yahoo). At the Scale tier ($0.03 per 1,000) that is $0.00006 per product compared; even a 5,000-product catalog sweep is $0.30 at Scale.
Are the two engines returning different products?
They share the same product source, so there is heavy overlap, but ordering and merchant mix differ. Treat it as a second look at the same market, and use SKU-level matching if you need to be certain two listings are the same product.



