A comprehensive comparison and implementation guide for building AI agents using Firecrawl and Crawl4AI - two powerful tools for extracting LLM-ready markdown from websites.
This project demonstrates how to:
- Extract clean, LLM-ready markdown from websites
- Build AI research agents that combine web scraping with GPT-4/Claude
- Compare two popular crawling approaches (API vs local)
- Choose the right tool for your use case
| Feature | Crawl4AI | Firecrawl |
|---|---|---|
| Cost | Free (open-source) | Paid API (~$0.001/page) |
| Setup | Medium (requires Playwright) | Easy (just API key) |
| Execution | Local | Cloud API |
| Rate Limits | None | API limits apply |
| Customization | High | Medium |
| Best For | High volume, cost-conscious | Quick start, production |
- Python 3.8 or higher
- pip package manager
- (Optional) API keys for Firecrawl, OpenAI, or Anthropic
- Clone the repository
git clone https://github.com/yourusername/ai-web-crawler-comparison.git
cd ai-web-crawler-comparison- Create a virtual environment
# On Windows
python -m venv venv
venv\Scripts\activate
# On macOS/Linux
python3 -m venv venv
source venv/bin/activate- Install dependencies
pip install -r requirements.txt
# For Crawl4AI, also install Playwright browsers
playwright install- Set up environment variables
# Copy the example env file
cp .env.example .env
# Edit .env and add your API keys
# - FIRECRAWL_API_KEY (get from https://firecrawl.dev)
# - OPENAI_API_KEY (optional, for GPT-4 examples)
# - ANTHROPIC_API_KEY (optional, for Claude examples)from crawl4ai_example import Crawl4AIScraper
import asyncio
async def main():
scraper = Crawl4AIScraper()
# Scrape a single page
result = await scraper.scrape_single_page("https://example.com")
print(result['markdown']) # Clean markdown output
print(result['metadata']) # Page metadata
asyncio.run(main())Run the demo:
python crawl4ai_example.pyfrom firecrawl_example import FirecrawlScraper
scraper = FirecrawlScraper()
# Scrape a single page
result = scraper.scrape_single_page("https://example.com")
print(result['markdown']) # Clean markdown outputRun the demo:
python firecrawl_example.pyBuild an agent that researches topics by crawling multiple sources:
from ai_agent import WebResearchAgent
import asyncio
async def main():
# Initialize agent (uses Crawl4AI + Claude by default)
agent = WebResearchAgent(
crawler_type="crawl4ai", # or "firecrawl"
llm_provider="anthropic" # or "openai"
)
# Research a topic across multiple URLs
answer = await agent.research_topic(
topic="What is machine learning?",
urls=[
"https://en.wikipedia.org/wiki/Machine_learning",
"https://www.ibm.com/topics/machine-learning"
]
)
print(answer)
asyncio.run(main())Run the demo:
python ai_agent.pyCompare both tools side-by-side:
python compare.pyThis will output:
- Speed comparison
- Content quality metrics
- Cost analysis
- Feature comparison table
ai-web-crawler-comparison/
├── firecrawl_example.py # Firecrawl implementation
├── crawl4ai_example.py # Crawl4AI implementation
├── ai_agent.py # AI agent combining crawling + LLM
├── compare.py # Side-by-side comparison script
├── requirements.txt # Python dependencies
├── .env.example # Environment variables template
└── README.md # This file
Crawl4AI:
scraper = Crawl4AIScraper()
urls = ["https://site1.com", "https://site2.com", "https://site3.com"]
results = await scraper.scrape_multiple_pages(urls)Firecrawl:
scraper = FirecrawlScraper()
result = scraper.crawl_website("https://example.com", max_pages=10)Firecrawl:
schema = {
"type": "object",
"properties": {
"title": {"type": "string"},
"price": {"type": "number"},
"features": {"type": "array", "items": {"type": "string"}}
}
}
result = scraper.extract_structured_data("https://product-page.com", schema)Crawl4AI:
result = await scraper.extract_with_css_selector(
"https://example.com",
css_selector=".product-info"
)scraper = Crawl4AIScraper()
chunks = await scraper.smart_chunking("https://long-article.com", chunk_size=1000)
# Each chunk is now optimal for LLM processing
for chunk in chunks:
# Send to your LLM
passAutomatically research topics by crawling authoritative sources and synthesizing information.
Summarize articles, documentation, or web pages using AI.
Extract structured data from websites for analysis or database population.
Build searchable knowledge bases from technical documentation.
Monitor competitor websites and generate insights.
Run each example to ensure everything works:
# Test Crawl4AI (no API key needed)
python crawl4ai_example.py
# Test Firecrawl (requires API key)
python firecrawl_example.py
# Test AI Agent (requires LLM API key)
python ai_agent.py
# Run full comparison
python compare.py- ✅ You want zero cost (completely free)
- ✅ You need to scrape high volumes of pages
- ✅ You want full control over the scraping process
- ✅ You're comfortable with local setup
- ✅ You need advanced customization
- ✅ You want the fastest setup (just an API key)
- ✅ You need production-grade reliability
- ✅ You value clean pre-processed output
- ✅ You prefer managed infrastructure
- ✅ Cost per page is acceptable
# Solution: Install Playwright browsers
playwright install# Solution: Make sure your .env file has FIRECRAWL_API_KEY set
# Get a key from https://firecrawl.dev# Solution: Verify your OpenAI or Anthropic API keys in .env
# Make sure you have credits in your account# Solution: Reinstall dependencies
pip install -r requirements.txt --force-reinstallThis project follows best practices:
- ✅ Type hints for better IDE support
- ✅ Comprehensive error handling
- ✅ Clear documentation and examples
- ✅ Rich console output for better UX
- ✅ Modular, reusable code structure
Contributions are welcome! To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Firecrawl team for their excellent API service
- Crawl4AI contributors for the open-source library
- OpenAI and Anthropic for their powerful LLM APIs
Questions or feedback? Open an issue on GitHub or reach out on my blog [https://www.rooteddreams.net]! This project is part of a deep-dive tutorial on my blog: [https://www.rooteddreams.net/web-scraping-software-open-source/]
If you found this helpful, please star the repo!