1. Scraping search results
Best Buy search pages show product cards with current and original prices, ratings, and SKU numbers. SnapRender bypasses Akamai bot protection and renders the JavaScript:
#E8A0BF">import requests
#E8A0BF">import json
API_KEY = #A8D4A0">"sr_live_YOUR_KEY"
#E8A0BF">def scrape_bestbuy_search(query, page=1):
#A8D4A0">""#A8D4A0">"Scrape Best Buy search results"#A8D4A0">""
url = f#A8D4A0">"https://www.bestbuy.com/site/searchpage.jsp?st={query}&cp={page}"
resp = requests.post(
#A8D4A0">"https://api.snaprender.dev/v1/extract",
headers={
#A8D4A0">"x-api-key": API_KEY,
#A8D4A0">"Content-Type": #A8D4A0">"application/json"
},
json={
#A8D4A0">"url": url,
#A8D4A0">"selectors": {
#A8D4A0">"names": #A8D4A0">".sku-title a",
#A8D4A0">"prices": #A8D4A0">".priceView-hero-price span:first-child",
#A8D4A0">"original_prices": #A8D4A0">".pricing-price__regular-price",
#A8D4A0">"ratings": #A8D4A0">".c-ratings-reviews-v4 span:first-child",
#A8D4A0">"review_counts": #A8D4A0">".c-ratings-reviews-v4 .c-reviews",
#A8D4A0">"skus": #A8D4A0">".sku-value",
#A8D4A0">"links": #A8D4A0">".sku-title a::attr(href)",
#A8D4A0">"savings": #A8D4A0">".pricing-price__savings"
},
#A8D4A0">"use_flaresolverr": true
}
)
#E8A0BF">return resp.json()[#A8D4A0">"data"]
# Scrape #A8D4A0">"4k tv" across 3 pages
all_products = []
#E8A0BF">for page #E8A0BF">in range(1, 4):
data = scrape_bestbuy_search(#A8D4A0">"4k+tv", page)
names = data.get(#A8D4A0">"names", [])
#E8A0BF">for i #E8A0BF">in range(len(names)):
all_products.append({
#A8D4A0">"name": names[i],
#A8D4A0">"price": data[#A8D4A0">"prices"][i] #E8A0BF">if i < len(data.get(#A8D4A0">"prices", [])) #E8A0BF">else #A8D4A0">"",
#A8D4A0">"original_price": data[#A8D4A0">"original_prices"][i] #E8A0BF">if i < len(data.get(#A8D4A0">"original_prices", [])) #E8A0BF">else #A8D4A0">"",
#A8D4A0">"rating": data[#A8D4A0">"ratings"][i] #E8A0BF">if i < len(data.get(#A8D4A0">"ratings", [])) #E8A0BF">else #A8D4A0">"",
#A8D4A0">"reviews": data[#A8D4A0">"review_counts"][i] #E8A0BF">if i < len(data.get(#A8D4A0">"review_counts", [])) #E8A0BF">else #A8D4A0">"",
#A8D4A0">"sku": data[#A8D4A0">"skus"][i] #E8A0BF">if i < len(data.get(#A8D4A0">"skus", [])) #E8A0BF">else #A8D4A0">"",
})
#E8A0BF">print(f#A8D4A0">"Page {page}: {len(names)} products")
#E8A0BF">print(f#A8D4A0">"Total: {len(all_products)} products scraped")2. Product detail extraction
Individual product pages include specs, descriptions, UPC codes, open-box pricing, and availability:
#E8A0BF">def scrape_bestbuy_product(product_url):
#A8D4A0">""#A8D4A0">"Scrape detailed product data #E8A0BF">from Best Buy"#A8D4A0">""
resp = requests.post(
#A8D4A0">"https://api.snaprender.dev/v1/extract",
headers={
#A8D4A0">"x-api-key": API_KEY,
#A8D4A0">"Content-Type": #A8D4A0">"application/json"
},
json={
#A8D4A0">"url": f#A8D4A0">"https://www.bestbuy.com{product_url}",
#A8D4A0">"selectors": {
#A8D4A0">"name": #A8D4A0">".sku-title h1",
#A8D4A0">"price": #A8D4A0">".priceView-hero-price span:first-child",
#A8D4A0">"original_price": #A8D4A0">".pricing-price__regular-price",
#A8D4A0">"savings": #A8D4A0">".pricing-price__savings",
#A8D4A0">"rating": #A8D4A0">".ugc-c-review-average",
#A8D4A0">"review_count": #A8D4A0">".ugc-c-review-count",
#A8D4A0">"sku": #A8D4A0">".product-data-value[data-automation=#A8D4A0">'sku']",
#A8D4A0">"upc": #A8D4A0">".product-data-value[data-automation=#A8D4A0">'upc']",
#A8D4A0">"model": #A8D4A0">".product-data-value[data-automation=#A8D4A0">'model']",
#A8D4A0">"description": #A8D4A0">".shop-product-description",
#A8D4A0">"specs": #A8D4A0">".key-features li",
#A8D4A0">"availability": #A8D4A0">".fulfillment-add-to-cart-button",
#A8D4A0">"open_box": #A8D4A0">".open-box-option__price"
},
#A8D4A0">"use_flaresolverr": true
}
)
#E8A0BF">return resp.json()[#A8D4A0">"data"]
product = scrape_bestbuy_product(
#A8D4A0">"/site/samsung-65-#E8A0BF">class-qn85d-series/6576428.p?skuId=6576428"
)
#E8A0BF">print(json.dumps(product, indent=2))3. Deal tracking
Best Buy runs daily deals, flash sales, and clearance events. Track deals automatically and monitor specific products:
#E8A0BF">import pandas #E8A0BF">as pd
#E8A0BF">import time
#E8A0BF">from datetime #E8A0BF">import datetime
#E8A0BF">class BestBuyDealTracker:
#E8A0BF">def __init__(self, api_key):
self.api_key = api_key
self.history_file = #A8D4A0">"bestbuy_deals.csv"
#E8A0BF">def scrape_deals_page(self):
#A8D4A0">""#A8D4A0">"Scrape the Best Buy deals page"#A8D4A0">""
resp = requests.post(
#A8D4A0">"https://api.snaprender.dev/v1/extract",
headers={
#A8D4A0">"x-api-key": self.api_key,
#A8D4A0">"Content-Type": #A8D4A0">"application/json"
},
json={
#A8D4A0">"url": #A8D4A0">"https://www.bestbuy.com/site/misc/deal-of-the-day/pcmcat248000050016.c",
#A8D4A0">"selectors": {
#A8D4A0">"names": #A8D4A0">".sku-title a",
#A8D4A0">"prices": #A8D4A0">".priceView-hero-price span:first-child",
#A8D4A0">"original_prices": #A8D4A0">".pricing-price__regular-price",
#A8D4A0">"savings": #A8D4A0">".pricing-price__savings",
#A8D4A0">"links": #A8D4A0">".sku-title a::attr(href)"
},
#A8D4A0">"use_flaresolverr": true
}
)
#E8A0BF">return resp.json()[#A8D4A0">"data"]
#E8A0BF">def track_products(self, product_urls):
#A8D4A0">""#A8D4A0">"Track specific product prices over time"#A8D4A0">""
results = []
timestamp = datetime.now().isoformat()
#E8A0BF">for url #E8A0BF">in product_urls:
#E8A0BF">try:
data = scrape_bestbuy_product(url)
results.append({
#A8D4A0">"timestamp": timestamp,
#A8D4A0">"url": url,
#A8D4A0">"name": data.get(#A8D4A0">"name", #A8D4A0">""),
#A8D4A0">"price": data.get(#A8D4A0">"price", #A8D4A0">""),
#A8D4A0">"original_price": data.get(#A8D4A0">"original_price", #A8D4A0">""),
#A8D4A0">"open_box": data.get(#A8D4A0">"open_box", #A8D4A0">""),
})
time.sleep(2)
#E8A0BF">except Exception #E8A0BF">as e:
#E8A0BF">print(f#A8D4A0">"Error: {url} - {e}")
df = pd.DataFrame(results)
df.to_csv(
self.history_file,
mode=#A8D4A0">"a",
header=#E8A0BF">not pd.io.common.file_exists(self.history_file),
index=#E8A0BF">False
)
#E8A0BF">return df
tracker = BestBuyDealTracker(API_KEY)
deals = tracker.scrape_deals_page()
#E8A0BF">print(f#A8D4A0">"Found {len(deals.get(#A8D4A0">'names', []))} deals today")Pro tip
Best Buy daily deals rotate at midnight CT. Schedule your deal scraper to run at 12:05 AM CT to catch new deals first. Open-box prices can drop significantly on weekday mornings.
4. Price analysis
Analyze scraped data to find the best deals and understand pricing patterns:
#E8A0BF">import pandas #E8A0BF">as pd
# Analyze scraped Best Buy product data
df = pd.DataFrame(all_products)
# Clean price data
df[#A8D4A0">"price_num"] = (
df[#A8D4A0">"price"]
.str.replace(#A8D4A0">"$", #A8D4A0">"", regex=#E8A0BF">False)
.str.replace(#A8D4A0">",", #A8D4A0">"", regex=#E8A0BF">False)
.astype(float)
)
df[#A8D4A0">"orig_num"] = (
df[#A8D4A0">"original_price"]
.str.extract(r#A8D4A0">"([\d,.]+)")
.replace(#A8D4A0">",", #A8D4A0">"", regex=#E8A0BF">True)
.astype(float)
)
df[#A8D4A0">"discount_pct"] = ((df[#A8D4A0">"orig_num"] - df[#A8D4A0">"price_num"]) / df[#A8D4A0">"orig_num"] * 100).round(1)
#E8A0BF">print(#A8D4A0">"=== Best Buy 4K TV Analysis ===")
#E8A0BF">print(f#A8D4A0">"Products found: {len(df)}")
#E8A0BF">print(f#A8D4A0">"Price range: $" + f#A8D4A0">"{df[#A8D4A0">'price_num'].min():.2f} - $" + f#A8D4A0">"{df[#A8D4A0">'price_num'].max():.2f}")
#E8A0BF">print(f#A8D4A0">"Median price: $" + f#A8D4A0">"{df[#A8D4A0">'price_num'].median():.2f}")
#E8A0BF">print(f#A8D4A0">"Avg discount: {df[#A8D4A0">'discount_pct'].mean():.1f}%")
# Best deals by discount percentage
best_deals = df.nlargest(10, #A8D4A0">"discount_pct")[[#A8D4A0">"name", #A8D4A0">"price", #A8D4A0">"original_price", #A8D4A0">"discount_pct"]]
#E8A0BF">print(#A8D4A0">"\n=== Biggest Discounts ===")
#E8A0BF">print(best_deals.to_string(index=#E8A0BF">False))
# Price tiers
tiers = pd.cut(
df[#A8D4A0">"price_num"],
bins=[0, 300, 500, 1000, 2000, float(#A8D4A0">"inf")],
labels=[#A8D4A0">"<$300", #A8D4A0">"$300-500", #A8D4A0">"$500-1K", #A8D4A0">"$1K-2K", #A8D4A0">"$2K+"]
)
#E8A0BF">print(#A8D4A0">"\n=== Price Tiers ===")
#E8A0BF">print(tiers.value_counts().sort_index())
df.to_csv(#A8D4A0">"bestbuy_4k_tvs.csv", index=#E8A0BF">False)Scrape Best Buy without getting blocked
SnapRender handles Akamai bot protection, JavaScript rendering, and structured data extraction. Get electronics pricing from Best Buy with a single API call.
Get Your API Key — FreeFrequently asked questions
Best Buy's Terms of Service prohibit automated data collection. Publicly displayed product data (prices, specs, reviews) can be accessed for personal research and price comparison. Do not republish product listings or use data to build a competing retail service.
Best Buy uses Akamai bot protection, JavaScript-rendered product pages, and frequently changes DOM structure. Product availability and pricing are loaded asynchronously via API calls. Standard HTTP requests return empty product containers.
Yes. Best Buy frequently runs sales, daily deals, and clearance events. Scrape the deals page and specific product URLs on a schedule to catch price drops. Open-box and clearance items have separate pricing that changes frequently.
Best Buy shows in-store availability by ZIP code on product pages. Include the store location parameter when scraping to get local inventory status. Note that inventory data is updated periodically and may not reflect real-time stock levels.
Product name, SKU, UPC, regular price, sale price, customer rating, review count, specifications, availability status, shipping options, and open-box pricing. Best Buy also shows competitor price match information on some products.