Automate Price Comparison Across Online Stores
March 6, 2026 · 7 min read
Building a price comparison engine used to mean scraping dozens of stores with custom code for each one. Today, ShelfRun handles detection, extraction, and normalization across compatible platforms so you can focus on the comparison logic itself.
The Architecture
A good price comparison system has three layers:
- Data extraction — Pull product data from multiple stores (ShelfRun handles this)
- Product matching — Identify which products across stores are the same item
- Comparison display — Show the best prices side by side
Step 1: Extract Data from Multiple Stores
Use ShelfRun to pull products from all your target stores simultaneously:
import asyncio
import aiohttp
API_KEY = "sr_live_your_key"
STORES = [
"store-a.com",
"store-b.com",
"store-c.com",
"store-d.com",
]
async def scan_store(session, url):
async with session.post(
"https://api.shelfrun.com/v1/quickscan",
headers={"X-API-Key": API_KEY},
json={"url": url}
) as resp:
data = await resp.json()
return {"store": url, "products": data["products"]}
async def scan_all():
async with aiohttp.ClientSession() as session:
tasks = [scan_store(session, s) for s in STORES]
return await asyncio.gather(*tasks)
results = asyncio.run(scan_all())
print(f"Scanned {len(results)} stores")Step 2: Match Products Across Stores
Match products by name similarity, SKU, or barcode. Here's a simple fuzzy-match approach:
from difflib import SequenceMatcher
def similarity(a, b):
return SequenceMatcher(None, a.lower(), b.lower()).ratio()
def find_matches(all_results, threshold=0.85):
"""Group same products across stores."""
groups = []
for store_data in all_results:
for product in store_data["products"]:
matched = False
for group in groups:
# Compare against first product in group
ref = group[0]["product"]
score = similarity(product["name"], ref["name"])
if score >= threshold:
group.append({
"store": store_data["store"],
"product": product,
"score": score
})
matched = True
break
if not matched:
groups.append([{
"store": store_data["store"],
"product": product,
"score": 1.0
}])
# Return only groups with 2+ stores
return [g for g in groups if len(g) > 1]
matches = find_matches(results)
print(f"Found {len(matches)} comparable product groups")Step 3: Find the Best Price
def best_price_report(matches):
report = []
for group in matches:
in_stock = [m for m in group if m["product"]["in_stock"]]
if not in_stock:
continue
cheapest = min(in_stock, key=lambda m: m["product"]["price"])
most_expensive = max(in_stock, key=lambda m: m["product"]["price"])
savings = most_expensive["product"]["price"] - cheapest["product"]["price"]
report.append({
"product": cheapest["product"]["name"],
"best_price": cheapest["product"]["price"],
"best_store": cheapest["store"],
"worst_price": most_expensive["product"]["price"],
"savings": round(savings, 2),
"stores_compared": len(in_stock)
})
return sorted(report, key=lambda r: r["savings"], reverse=True)
report = best_price_report(matches)
for item in report[:10]:
name = item['product']
price = item['best_price']
store = item['best_store']
saved = item['savings']
print(name + ": best $" + str(price) + " at " + store + " (save $" + str(saved) + ")")Use ShelfRun's Built-in Compare Feature
For simpler use cases, ShelfRun's dashboard includes a built-in comparison view that shows products from all your monitored stores side by side — no code required.
Keeping Data Fresh
Price comparison is only useful if data is current. Set up scheduled syncs for each store:
import requests
for store_url in STORES:
requests.post(
"https://api.shelfrun.com/v1/stores",
headers={"X-API-Key": API_KEY},
json={
"url": store_url,
"sync_frequency": "hourly", # or "daily"
"webhook_url": "https://yourapp.com/price-update"
}
)
# Your webhook receives updates as they happen —
# no polling requiredUse Cases for Multi-Store Comparison
- Consumer price comparison sites: Build the next Google Shopping or PriceGrabber
- Retail analytics: Show clients where they sit in the market
- Procurement tools: Find the cheapest supplier for a given SKU across multiple vendors
- Dynamic repricing: Automatically adjust your prices to stay competitive
- Marketplace compliance: Ensure your sellers aren't undercutting MAP pricing