# Best Buy Scraper (`crawlerbros/bestbuy-scraper`) Actor

Scrape Best Buy product listings by search keyword or product URL. Extracts SKU, price, sale price, rating, review count, model, brand, availability, and seller info. HTTP-only with hardcoded residential-proxy fallback.

- **URL**: https://apify.com/crawlerbros/bestbuy-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 17 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Best Buy Scraper

Scrape Best Buy product listings by search keyword or specific product URLs. Each result is a flat record with SKU, regular + sale price, rating, brand, model, availability, and seller info. Routes through Apify residential proxy automatically when Best Buy's bot challenge fires (no proxy input needed).

### What it does

You provide a search keyword and / or a list of product URLs; the actor:

1. (If `keyword` set) Walks Best Buy's `searchpage.jsp` for matching products, paginating up to ~24 results per page.
2. Hits each product detail page and parses `application/ld+json` Product schema + `__NEXT_DATA__` prices.
3. Optionally drops out-of-stock SKUs.
4. Auto-rotates Apify residential-proxy sessions when the direct request is fingerprinted as a bot.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `keyword` | string | `sony headphones` | Free-text search — product name, brand, category. Use `keyword` *or* `productUrls`, or both. |
| `productUrls` | array of strings | `[]` | Specific Best Buy product URLs (e.g. `https://www.bestbuy.com/site/.../6505729.p?skuId=6505729`). |
| `maxResults` | integer | `24` (1–240) | Hard cap on records. |
| `skipOutOfStock` | boolean | `false` | Drop products marked out-of-stock / sold-out. |

#### Example input

```json
{
  "keyword": "sony headphones",
  "productUrls": [
    "https://www.bestbuy.com/site/sony-wh-1000xm5-wireless-noise-canceling-over-the-ear-headphones-black/6505729.p?skuId=6505729"
  ],
  "maxResults": 24,
  "skipOutOfStock": false
}
````

### Output

One record per product. Empty fields are omitted (no nulls).

```json
{
  "sku": "6505729",
  "url": "https://www.bestbuy.com/site/sony-wh-1000xm5-wireless-noise-canceling-over-the-ear-headphones-black/6505729.p?skuId=6505729",
  "name": "Sony - WH-1000XM5 Wireless Noise Canceling Over-the-Ear Headphones - Black",
  "brand": "Sony",
  "model": "WH1000XM5/B",
  "image": "https://pisces.bbystatic.com/.../6505729_sd.jpg",
  "imageUrl": "https://pisces.bbystatic.com/.../6505729_sd.jpg",
  "currentPrice": 299.99,
  "regularPrice": 399.99,
  "salePrice": 299.99,
  "savings": 100.00,
  "savingsPercent": 25,
  "onSale": true,
  "currency": "USD",
  "currencySymbol": "$",
  "availability": "InStock",
  "seller": "Best Buy",
  "rating": 4.7,
  "reviewCount": 6420,
  "description": "Industry-leading noise cancellation…",
  "scrapedAt": "2026-04-26T14:23:11+00:00"
}
```

#### Output fields

- **`sku`** — Best Buy's stable product SKU (extracted from `…/<sku>.p` path).
- **`url`** — direct link to the product detail page.
- **`name`** / **`description`** — product title and marketing description.
- **`brand`** / **`model`** — manufacturer + model number.
- **`image`** / **`imageUrl`** — primary product image URL. `imageUrl` is an alias for downstream-pipeline compatibility.
- **`currentPrice`** — price currently shown to the shopper.
- **`regularPrice`** / **`salePrice`** — non-sale price + sale price when on promotion.
- **`savings`** — derived: `regularPrice - salePrice` (only when both are present and sale price is lower).
- **`savingsPercent`** — derived: `round(100 * savings / regularPrice)`.
- **`onSale`** — derived boolean: `true` when `salePrice < regularPrice`.
- **`currency`** — ISO currency (always `USD` at .com).
- **`currencySymbol`** — display symbol (`$`, `€`, `£`, etc.) corresponding to `currency`.
- **`availability`** — `InStock`, `OutOfStock`, `PreOrder`, `BackOrder`, `LimitedAvailability`.
- **`seller`** — usually `Best Buy`; third-party marketplace sellers also appear.
- **`rating`** / **`reviewCount`** — aggregate review stats from Best Buy's customer reviews.
- **`scrapedAt`** — ISO-8601 UTC timestamp.

### Use cases

- **Price monitoring** — track regular vs sale price across a watch-list of SKUs.
- **Stock alerts** — combine with `skipOutOfStock: false` to detect when an item flips back to `InStock`.
- **Product research** — pull every Sony headphone on Best Buy in one run.
- **Competitive analysis** — compare Best Buy face-value with other retailers.
- **Review aggregation** — collect rating / review-count snapshots for trend analysis.

### FAQ

**Does it need a proxy?**
Not as input — the actor automatically uses Apify's residential proxy whenever Best Buy's bot-challenge fires. Keyword search renders Best Buy's React shell in a headless Chromium with the residential proxy attached; product detail pages prefer a faster HTTP-only fetch and fall back to the proxy on block.

**Is it the official API?**
No — this scraper extracts from the Best Buy website's embedded JSON-LD + `__NEXT_DATA__`. Best Buy does ship a developer API for affiliates (developer.bestbuy.com) for high-volume programmatic access.

**Why are some fields missing?**
Best Buy doesn't always populate every field. The actor follows an omit-empty contract: fields that aren't present on the source page are simply absent from the record (no nulls).

**How many results can it return?**
Up to `maxResults` (max 240, ~10 pages of results). Each product page is fetched individually — expect ~1.5–3s per product including the proxy retry budget.

**Can I scrape category pages?**
Yes — paste any Best Buy category / collection URL into `productUrls` (the actor walks anchor links on the page). Or use the `keyword` field for the standard search experience.

**Why was a specific SKU skipped?**

- `skipOutOfStock: true` drops items flagged out-of-stock.
- Bot-challenge persisted across all proxy retries (rare, ~5% of requests).
- The page didn't ship JSON-LD nor `__NEXT_DATA__` (very rare, malformed listing).

# Actor input Schema

## `keyword` (type: `string`):

Free-text search — product name, brand, category. Leave empty if you're using `productUrls` instead.

## `productUrls` (type: `array`):

Specific Best Buy product page URLs to scrape (e.g. `https://www.bestbuy.com/site/.../6505729.p?skuId=6505729`). Used in addition to / instead of `keyword`.

## `maxResults` (type: `integer`):

Hard cap on records emitted across keyword search + URL scrape.

## `skipOutOfStock` (type: `boolean`):

Drop products marked `out of stock` / `sold out` by Best Buy.

## Actor input object example

```json
{
  "keyword": "sony headphones",
  "productUrls": [],
  "maxResults": 24,
  "skipOutOfStock": false
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keyword": "sony headphones"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/bestbuy-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "keyword": "sony headphones" }

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/bestbuy-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keyword": "sony headphones"
}' |
apify call crawlerbros/bestbuy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/bestbuy-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Best Buy Scraper",
        "description": "Scrape Best Buy product listings by search keyword or product URL. Extracts SKU, price, sale price, rating, review count, model, brand, availability, and seller info. HTTP-only with hardcoded residential-proxy fallback.",
        "version": "0.1",
        "x-build-id": "QD8wBgaLywBzv1qEf"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/crawlerbros~bestbuy-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-crawlerbros-bestbuy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/crawlerbros~bestbuy-scraper/runs": {
            "post": {
                "operationId": "runs-sync-crawlerbros-bestbuy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/crawlerbros~bestbuy-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-crawlerbros-bestbuy-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "keyword": {
                        "title": "Search keyword",
                        "type": "string",
                        "description": "Free-text search — product name, brand, category. Leave empty if you're using `productUrls` instead."
                    },
                    "productUrls": {
                        "title": "Product URLs",
                        "type": "array",
                        "description": "Specific Best Buy product page URLs to scrape (e.g. `https://www.bestbuy.com/site/.../6505729.p?skuId=6505729`). Used in addition to / instead of `keyword`.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 1,
                        "maximum": 240,
                        "type": "integer",
                        "description": "Hard cap on records emitted across keyword search + URL scrape.",
                        "default": 24
                    },
                    "skipOutOfStock": {
                        "title": "Skip out-of-stock",
                        "type": "boolean",
                        "description": "Drop products marked `out of stock` / `sold out` by Best Buy.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
