Skip to content

Scraping Amazon with Firecrawl

Updated Feb 2026

Amazon is one of the most commonly scraped e-commerce sites. Firecrawl handles anti-bot protections, JavaScript rendering, and structured data extraction so you can focus on the data you need.

Installation

bash
npm install @mendable/firecrawl-js zod
bash
# Or with Python
pip install firecrawl-py

JSON Mode: Structured Product Extraction

Use JSON mode with a Zod schema to extract validated, structured product data from any Amazon product page.

TypeScript

typescript
import FirecrawlApp from "@mendable/firecrawl-js";
import { z } from "zod";

const app = new FirecrawlApp({ apiKey: process.env.FIRECRAWL_API_KEY });

// Define the product schema
const productSchema = z.object({
  title: z.string().describe("Product title"),
  price: z.string().describe("Current price including currency symbol"),
  originalPrice: z.string().optional().describe("Original price before discount"),
  rating: z.string().describe("Star rating out of 5"),
  reviewCount: z.string().describe("Total number of reviews"),
  availability: z.string().describe("In stock, out of stock, or limited availability"),
  features: z.array(z.string()).describe("Key product features / bullet points"),
  seller: z.string().optional().describe("Sold by / seller name"),
  brand: z.string().optional().describe("Brand name"),
});

const result = await app.scrapeUrl(
  "https://www.amazon.com/dp/B0EXAMPLE123",
  {
    formats: ["json"],
    jsonOptions: {
      schema: productSchema,
    },
  }
);

console.log(result.json);
// {
//   title: "Example Product Name",
//   price: "$29.99",
//   rating: "4.5",
//   reviewCount: "1,234",
//   availability: "In Stock",
//   features: ["Feature 1", "Feature 2", "Feature 3"],
//   seller: "ExampleSeller",
//   brand: "ExampleBrand"
// }

Python

python
from firecrawl import FirecrawlApp
from pydantic import BaseModel
from typing import Optional

app = FirecrawlApp(api_key="fc-YOUR_API_KEY")

class ProductSchema(BaseModel):
    title: str
    price: str
    original_price: Optional[str] = None
    rating: str
    review_count: str
    availability: str
    features: list[str]
    seller: Optional[str] = None
    brand: Optional[str] = None

result = app.scrape_url(
    "https://www.amazon.com/dp/B0EXAMPLE123",
    params={
        "formats": ["json"],
        "jsonOptions": {
            "schema": ProductSchema.model_json_schema(),
        },
    },
)

print(result["json"])

Search: Find Products Programmatically

Use Firecrawl's search endpoint to find Amazon products by query without constructing URLs manually.

typescript
const results = await app.search("gaming laptop site:amazon.com", {
  limit: 5,
  scrapeOptions: {
    formats: ["markdown"],
  },
});

for (const result of results.data) {
  console.log(`${result.title} - ${result.url}`);
}

Scrape: Single Page Content

Extract a product page as clean markdown for LLM processing or content analysis.

typescript
const result = await app.scrapeUrl(
  "https://www.amazon.com/dp/B0EXAMPLE123",
  {
    formats: ["markdown", "links"],
  }
);

console.log(result.markdown);  // Clean product description
console.log(result.links);     // Related product links

Map: Discover URLs

Use Map to discover all product URLs in a category or search results page without extracting content.

typescript
const urls = await app.mapUrl(
  "https://www.amazon.com/s?k=wireless+headphones"
);

console.log(`Found ${urls.links.length} URLs`);
// Filter to product pages only
const productUrls = urls.links.filter((url) =>
  url.includes("/dp/")
);

Crawl: Multi-Page Extraction

Crawl search result pages to collect multiple products in a single operation.

typescript
const crawlResult = await app.crawlUrl(
  "https://www.amazon.com/s?k=wireless+headphones",
  {
    limit: 20,
    scrapeOptions: {
      formats: ["markdown"],
    },
  }
);

for (const page of crawlResult.data) {
  console.log(`Scraped: ${page.metadata.title}`);
}

Batch Scrape: Multiple Products in Parallel

When you have a list of product URLs, batch scrape processes them simultaneously.

typescript
const productUrls = [
  "https://www.amazon.com/dp/B0EXAMPLE001",
  "https://www.amazon.com/dp/B0EXAMPLE002",
  "https://www.amazon.com/dp/B0EXAMPLE003",
];

const batchResult = await app.batchScrapeUrls(productUrls, {
  formats: ["json"],
  jsonOptions: {
    schema: productSchema,
  },
});

// Poll for completion
console.log(`Status: ${batchResult.status}`);
console.log(`Completed: ${batchResult.completed}/${batchResult.total}`);

for (const product of batchResult.data) {
  console.log(`${product.json.title}: ${product.json.price}`);
}

Anti-Bot Handling

Amazon uses aggressive anti-bot protections. Firecrawl handles these automatically, but keep these tips in mind:

Use the Correct Proxy Mode

For Amazon and other heavily-protected sites, enable Firecrawl's stealth/enhanced mode for better success rates:

typescript
const result = await app.scrapeUrl(
  "https://www.amazon.com/dp/B0EXAMPLE123",
  {
    formats: ["json"],
    jsonOptions: { schema: productSchema },
    // Firecrawl automatically selects the best proxy
    // For difficult pages, the platform escalates proxy tiers
  }
);

Best Practices

PracticeWhy
Add delays between requestsAvoid triggering rate limits
Use batch scrape over sequential callsFirecrawl manages concurrency and retries
Scrape product pages (/dp/) not search pagesProduct pages have more structured, extractable data
Define precise schemasExtract only what you need -- reduces processing time
Handle null fields gracefullySome products lack ratings, reviews, or seller info

Price Monitoring Example

Combine batch scrape with a schedule to build a price tracker:

typescript
import FirecrawlApp from "@mendable/firecrawl-js";
import { z } from "zod";

const app = new FirecrawlApp({ apiKey: process.env.FIRECRAWL_API_KEY });

const priceSchema = z.object({
  title: z.string(),
  price: z.string(),
  availability: z.string(),
});

async function checkPrices(urls: string[]) {
  const results = await app.batchScrapeUrls(urls, {
    formats: ["json"],
    jsonOptions: { schema: priceSchema },
  });

  for (const item of results.data) {
    const { title, price, availability } = item.json;
    console.log(`${title}: ${price} (${availability})`);

    // Compare with stored prices, send alerts, etc.
  }
}

// Run with your tracked product URLs
checkPrices([
  "https://www.amazon.com/dp/B0EXAMPLE001",
  "https://www.amazon.com/dp/B0EXAMPLE002",
]);

WARNING

Always review Amazon's Terms of Service before scraping. Use scraped data responsibly and in compliance with applicable laws.

Resources