Google Shopping SKU Matching in Python: Competitor Product Matching That Does Not Lie
Method note: Measurements in this article were run locally against authenticated Serpent API endpoints on August 3, 2026. Sample sizes are stated in the article. Treat the numbers as a dated field check, not a permanent guarantee.
Short answer: SKU matching is not price monitoring. It is the step before price monitoring where you prove two listings describe the same product. If you skip it, your dashboard compares an AirPods case to AirPods Pro and calls it a discount.
For this test I reused the five product queries from the Shopping field audit. The normalized shopping block was absent in this local run, so the matcher used the top organic product candidates. The important result is the method: score matches, bucket confidence, and keep low-confidence rows out of price intelligence.
Measured Candidate Scores
The first pass used simple title-token overlap. That is deliberately conservative and easy to audit. Four queries had all five top candidates at a 1.0 token score; "kindle paperwhite" had one 0.5 candidate that should be reviewed before use.
| Query | Candidate scores |
|---|---|
| sony wh-1000xm5 | 1, 1, 1, 1, 1 |
| airpods pro 2 | 1, 1, 1, 1, 1 |
| dyson v15 detect | 1, 1, 1, 1, 1 |
| nintendo switch oled | 1, 1, 1, 1, 1 |
| kindle paperwhite | 1, 1, 1, 1, 0.5 |
The Matching Pipeline
import re
from urllib.parse import urlparse
STOP = {"the", "for", "with", "new", "official"}
def tokens(text):
return [t for t in re.split(r"[^a-z0-9]+", text.lower()) if t and t not in STOP]
def score(query, candidate_title):
q = tokens(query)
title = candidate_title.lower()
hits = sum(1 for t in q if t in title)
return round(hits / max(len(q), 1), 2)
def bucket(score):
if score >= 0.85:
return "auto_match"
if score >= 0.60:
return "review"
return "reject"
for candidate in candidates:
s = score("kindle paperwhite", candidate["title"])
print(candidate["title"], s, bucket(s))
False Matches to Exclude
Reject accessories, bundles, refurbished-only listings, old model years, and pages where the model token appears only in a comparison table. A practical matcher should also add negative tokens: "case", "charger", "screen protector", "used", "renewed", and "compatible with".
Where It Fits
Use this before any price monitoring or ecommerce price intelligence workflow. First match the product. Then compare price. Link it to the Google SERP API output you actually observed — or pull a dedicated product listing grid from the Shopping API using the Google Shopping API engine when you want product data without parsing organic SERPs.
FAQ
What is SKU matching?
SKU matching is entity resolution for products: deciding whether two titles, sellers, and URLs represent the same real product.
Why not match on price first?
Price changes too often. Match on model tokens, brand, variant, capacity, color, and seller context before comparing price.
What did the August 2026 sample show?
The five product queries produced organic candidates with high title-token overlap, but no normalized shopping block in that local run.



