How to Scrape Any Website Using Firecrawl in 2026

A step-by-step Firecrawl tutorial using the current SDK: scrape a page, crawl a site, extract JSON with a schema, read PDFs, set location and proxies, and fix empty results.

Author
ProxyHorizon Team
Published
June 8, 2026
9 min read
Expert-Verified
How to Scrape Any Website Using Firecrawl in 2026

Most scraping tutorials teach you to hunt for CSS selectors. Then the site renames one class, and your scraper quietly returns nothing.

Firecrawl skips selectors entirely. You give it a URL, and it hands back clean Markdown, HTML or structured JSON, even from pages built with JavaScript.

This guide walks through it with the current SDK, from your first scrape to crawling a whole site and pulling out exact fields. If you’ve copied Firecrawl code from an older tutorial and it won’t run, the SDK changing is probably why.

There’s also a popular piece of advice about Firecrawl and proxies that’s only half true. We’ll clear it up before you spend money on it.

TL;DR
  • Firecrawl turns any URL into clean Markdown, HTML or structured JSON with one API call.
  • The current Python SDK uses a Firecrawl class with scrape, crawl and map methods, so code from older tutorials won’t run as written.
  • A plain scrape costs 1 credit per page, and JSON extraction costs 5.
  • Firecrawl Cloud runs every request through its own proxies. Your own proxies only come into play when you self-host.
  • Most empty results come from JavaScript that hasn’t finished loading.

What Firecrawl Does, and What It Doesn’t

Firecrawl is a web data API. It loads a page in a real browser and strips the clutter. Then it returns the content in the format you ask for: Markdown, HTML, a screenshot or JSON that matches your schema.

It covers more than single pages. It can crawl a whole site, list every URL on a domain, search the web and read PDFs. The output is built for language models, which is why it’s so popular in AI pipelines. Our Firecrawl review covers the full feature set.

Diagram of what a managed scraping API adds on top of a browser engine: anti-bot layer, proxy routing and clean output
Firecrawl wraps a browser with anti-bot handling, proxies and clean output.

What it doesn’t do is guarantee access to every site. Heavily protected pages can still block it, and it doesn’t make scraping a site legal. We’ll come back to both.

If you’re new to all this, start with what web scraping is. The Firecrawl links on this page are affiliate links, so we may earn a commission if you sign up.

What It Costs Before You Start

Firecrawl bills in credits. The free plan includes 1,000 a month, which is plenty to follow this guide. Here’s what each action costs, from Firecrawl’s pricing page in September 2026.

ActionCredits
Scrape one page1
Crawl1 per page
Map1 per page
JSON output4 extra per page, so 5 in total
Search2 per 10 results
Enhanced proxiesNo extra charge

Paid plans start at $16 a month for 5,000 credits, billed yearly. The cost that surprises people is JSON, so keep that line of the table in mind for later.

Step 1: Get Your API Key

Sign up on Firecrawl’s site and copy your API key from the dashboard. Firecrawl’s docs note that you can try it without a key at lower rate limits, but you’ll want one for anything real.

Keep the key out of your code. Store it in an environment variable called FIRECRAWL_API_KEY and read it from there.

Step 2: Install the SDK

Firecrawl has official SDKs for Python and Node.js, plus a plain REST API. Install the one that matches your stack.

Text
# Python
pip install firecrawl-py

# Node.js
npm install firecrawl

Both SDKs wrap the same API, so everything below works in either language. We’ll use Python.

Step 3: Scrape Your First Page

With the SDK installed and your key set, a single-page scrape takes a few lines.

Text
import os
from firecrawl import Firecrawl

firecrawl = Firecrawl(api_key=os.environ["FIRECRAWL_API_KEY"])

doc = firecrawl.scrape("https://example.com", formats=["markdown", "html"])
print(doc.markdown)

That’s the whole thing. You get the page back as Markdown and HTML, ready to store or pass to a language model. There are no selectors to write and no browser to set up.

Old code warning: tutorials written for the earlier SDK use FirecrawlApp and scrape_url(params=...). The current SDK uses Firecrawl and scrape() with plain keyword arguments, as shown above.

Fixing Empty or Messy Pages

Two settings fix most bad results. Here they are together.

Text
doc = firecrawl.scrape(
    "https://news.example.com/article",
    formats=["markdown"],
    only_main_content=True,
    wait_for=2000,
)

only_main_content strips menus, footers and ads, so you keep the article and lose the noise. wait_for pauses for 2,000 milliseconds, giving JavaScript time to load the content.

Why does that matter? Many modern sites send an almost empty page first, then fill it in with JavaScript. Scrape too early and you get the empty shell. If a page still comes back blank, raise the wait before you blame the tool.

Crawling a Whole Site

When you need more than one page, crawl() follows links across a site and returns every page it finds. It’s how you pull a whole documentation site or blog into a dataset.

Text
crawl = firecrawl.crawl(
    "https://docs.example.com",
    limit=100,
    scrape_options={"formats": ["markdown"]},
)

print(crawl.status, crawl.completed, crawl.credits_used)
for page in crawl.data:
    print(page.metadata.source_url)

The limit caps how many pages get crawled, so a big site can’t drain your credits in one run. This call waits until the crawl finishes. For large jobs, start_crawl() runs it in the background so your script can carry on.

Not sure which pages you need? Run firecrawl.map(url="https://docs.example.com", limit=50) first. It lists a site’s URLs, so you can crawl only the sections that matter. Our guide to scraping large websites with Firecrawl goes deeper on crawl settings.

Extracting Structured Data With a Schema

This is where Firecrawl shines. Instead of text, you ask for JSON that matches a schema you define, and a language model fills in the fields.

Text
from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    in_stock: bool

doc = firecrawl.scrape(
    "https://store.example.com/item/123",
    formats=[{"type": "json", "schema": Product.model_json_schema()}],
)
print(doc.json)

There are no parsing rules to write, and nothing to fix when the page layout changes. The schema stays the same even when the markup doesn’t.

Don’t need a strict schema? Swap it for a prompt, such as {"type": "json", "prompt": "Extract the product name and price"}, and Firecrawl picks the fields for you.

Diagram of schema-based extraction: a web page or document goes through an extractor, is matched to your schema, and comes out as clean JSON
Describe the fields once, and get clean JSON back from any layout.

Watch the cost: JSON output costs 5 credits a page, five times a plain scrape. A model can also guess when a field is missing, so validate the output before you trust it. Our guide to data extraction APIs shows how.

1Scraping PDFs

Firecrawl reads PDFs the same way it reads web pages. Point scrape() at the file and ask for Markdown.

Text
doc = firecrawl.scrape("https://example.com/report.pdf", formats=["markdown"])
print(doc.markdown)

That’s handy for annual reports, manuals and research papers, where copying text by hand mangles the tables.

2Searching Before You Scrape

Sometimes you don’t have a URL yet, only a question. search() runs a web search and returns the top results.

Text
results = firecrawl.search("static residential proxies explained", limit=5)
for result in results.web:
    print(result.title, result.url)

Search costs 2 credits per 10 results. Feed the best URLs into scrape(), and you have a small research pipeline in a dozen lines.

Firecrawl and Proxies: What the Docs Actually Say

Here’s the half-true advice from the top of this guide. You’ll often read that you should pair Firecrawl with your own proxies. On Firecrawl Cloud, the docs don’t offer a way to plug them in, and you don’t need to.

Firecrawl routes every request through its own proxies by default, using US IPs unless you say otherwise. You control them with two settings.

Text
doc = firecrawl.scrape(
    "https://shop.example.de/angebote",
    formats=["markdown"],
    location={"country": "DE", "languages": ["de"]},
    proxy="auto",
)

location picks the country and language from the 26 countries listed in Firecrawl’s proxy docs. proxy="auto" retries with enhanced proxies if a basic request fails, and enhanced requests cost no extra credits.

One catch: ask for a country outside that list, and Firecrawl uses the nearest EU or US proxy. It only sets the browser’s location to match, so the site may still see a foreign IP.

Comparison of Firecrawl Cloud, which includes proxies and a country setting with no setup, versus self-hosted Firecrawl, which needs your own proxies set in environment settings on your own servers
Firecrawl Cloud brings its own proxies. Self-hosted Firecrawl needs yours.

Your own proxies come into play when you self-host Firecrawl. The open-source version reads a proxy from three settings in its .env file: PROXY_SERVER, PROXY_USERNAME and PROXY_PASSWORD.

That’s also where proxies matter most. The self-hosted version leaves out Fire-engine, Firecrawl’s anti-bot service, so residential proxies have to do more of the work. Our Firecrawl alternatives guide covers what else self-hosting leaves out.

Proxies for Self-Hosted Firecrawl

If you self-host, these three providers work well with Firecrawl’s proxy settings. The proxy cards link to our partners, so we may earn a commission if you sign up. You can compare more in our proxy directory.

1Decodo

Pool:115M+
Uptime:99.99%
Latency:0.6s
Countries:195+
Huge 97M+ residential IP pool
Beginner-friendly dashboard and documentation
Flexible pay-as-you-go pricing
High success rates on tough targets
Fast 24/7 live chat support
Free trial and money-back guarantee

Decodo’s residential network covers more than 115 million IPs in 195 countries, with a clean dashboard and simple username-and-password setup. That fits Firecrawl’s three proxy settings neatly.

Its country and city targeting also fills the gap Firecrawl Cloud leaves: local IPs in countries outside its list of 26.

2IPRoyal

Pool:64M+
Uptime:99.9%
Latency:0.8s
Countries:195+
Traffic never expires (pay-as-you-go)
Ethically sourced residential IPs
Crypto and flexible payment options
Affordable entry pricing
Sticky sessions up to 24 hours

IPRoyal’s residential traffic never expires, which suits crawls that run in bursts rather than every day. Its pool covers more than 64 million IPs in 195 countries.

Sticky sessions help when a site expects the same IP across several pages, like a paginated listing.

3Oxylabs

Pool:102M+
Uptime:99.99%
Latency:0.6s
Countries:195+
Massive 102M+ IP Pool
Ethically Sourced & Compliant
AI-Powered Web Unblocker
Dedicated Account Manager
Advanced ASN & City Targeting

Oxylabs is the enterprise choice, with a residential pool of more than 102 million IPs and dedicated account support. It’s built for crawls that run all day, every day.

Pick it when uptime and support matter more than price.

Mistakes That Waste Time and Credits

1Crawling Without a Limit

Launch a crawl on a big site without a limit, and one run can use your whole month of credits. Start small, check the output, then scale up. Treat the first crawl of any new domain as a test.

2Paying JSON Prices for Plain Text

If you’ll read the text yourself or pass it straight to a language model, ask for Markdown. It costs 1 credit a page instead of 5. Save JSON for fields you need in a database.

3Blaming the Tool for Protected Sites

If a site keeps blocking you, set proxy="auto" before you give up. For the toughest targets, our guide to bypassing Cloudflare when scraping covers what else helps.

4Ignoring Robots.txt and Site Terms

Just because you can scrape a page doesn’t mean you should. Check the site’s terms and robots.txt, avoid collecting personal data without a lawful basis, and keep your request rate gentle.

Where Firecrawl Fits Best

Firecrawl earns its place wherever pages change often and you’d rather not maintain selectors.

  • AI knowledge bases: crawl a documentation site and feed the Markdown into a vector database. Our guide to using Firecrawl for RAG shows the full pipeline.
  • Price monitoring: pull product names, prices and stock status on a schedule with a JSON schema.
  • Lead lists: extract company details from directory pages in the same shape every time.
  • Research datasets: collect reviews or listings as clean records, ready to analyze.

Frequently Asked Questions

Start Small, Then Let It Crawl

Firecrawl turns scraping from a maintenance job into a few lines of code. Scrape one page, fix empty results with a short wait, crawl with a limit, and switch to JSON only when you need exact fields.

And remember the proxy rule: on Firecrawl Cloud, pick a country with location and let Firecrawl handle the rest. Bring your own proxies only when you self-host.

Your next step: take one page you currently copy by hand and reproduce it with scrape(). Then map the site and crawl just the section you need. Want the bigger picture? Our guide to web scraping with Python covers the rest of the toolkit.