A browser crawler built to get past bot protection. Uses Camoufox, a Firefox build that looks like a real user.
Create it locally
$scrapely create my-actor --template python-crawlee-playwright-camoufox
Main file
.PY
my_actor/main.pyfrom scrapely import Actor
from camoufox import AsyncNewBrowser
from crawlee.browsers import BrowserPool, PlaywrightBrowserController, PlaywrightBrowserPlugin
from crawlee.crawlers import PlaywrightCrawler
from typing_extensions import override
from .routes import router
class CamoufoxPlugin(PlaywrightBrowserPlugin):
"""Browser plugin that uses Camoufox Browser, but otherwise keeps the functionality of PlaywrightBrowserPlugin."""
@override
async def new_browser(self) -> PlaywrightBrowserController:
if not self._playwright:
raise RuntimeError('Playwright browser plugin is not initialized.')
return PlaywrightBrowserController(
browser=await AsyncNewBrowser(self._playwright, headless=True),
max_open_pages_per_browser=1, # Increase, if camoufox can handle it in your use case.
header_generator=None, # This turns off the crawlee header_generation. Camoufox has its own.
)
async def main() -> None:
"""Define a main entry point for the Scrapely Actor.
This coroutine is executed using `asyncio.run()`, so it must remain an asynchronous function for proper execution.
Asynchronous execution is required for communication with Scrapely platform, and it also enhances performance in
the field of web scraping significantly.
"""
# Enter the context of the Actor.
async with Actor:
# Retrieve the Actor input, and use default values if not provided.
actor_input = await Actor.get_input() or {}
start_urls = [
url.get('url')
for url in actor_input.get(
'start_urls',
[{'url': 'https://crawlee.dev'}],
)
]
# Exit if no start URLs are provided.
if not start_urls:
Actor.log.info('No start URLs specified in Actor input, exiting...')
await Actor.exit()
# Create a crawler.
crawler = PlaywrightCrawler(
# Limit the crawl to max requests. Remove or increase it for crawling all links.
max_requests_per_crawl=10,
browser_pool=BrowserPool(plugins=[CamoufoxPlugin()]),
# Set the request handler to the request router defined in routes.py.
request_handler=router,
)
# Run the crawler with the starting requests.
await crawler.run(start_urls)
Python stealth crawler (Crawlee + Playwright + Camoufox)
A browser crawler built to get past bot protection. Uses Camoufox, a Firefox build that looks like a real user.
Included features
- Scrapely SDK — Actor lifecycle, input, storage and proxies
- Crawlee — crawling, request queues, retries and storage
- Playwright — headless browser automation
- Camoufox — stealth Firefox build
- Input schema — define and validate the Actor's input (
.actor/input_schema.json) - Dataset schema — structured results with a preview view (
.actor/dataset_schema.json)
Getting started locally
python -m pip install -r requirements.txt
scrapely run # run the Actor locally
Deploying to Scrapely
Create an Actor from this template in the Scrapely Console (Develop new → template → Git). Scrapely creates a repository in your account, pushes this code, and builds the Actor. Every push to your repository triggers a new build.