Python SDK
Install and use mrscraper-sdk, the typed async Python client for the MrScraper API, to fetch page content with the Scraper API and get real-time web search results with asyncio.
The mrscraper-sdk is a typed Python client for the MrScraper API. It exposes three methods: scraper_api to fetch page content (HTML, Markdown, or screenshots), web_search to retrieve real-time web search results, and account to check your subscription and token usage. All client methods are async and must be used with asyncio or another async runtime.
Requirements
- Python 3.9 or later
- Basic familiarity with async/await syntax in Python
Package Information
This page documents version 0.9.0. See the mrscraper-sdk on PyPI for the latest release, version history, and metadata.
Installation
Install the SDK from PyPI using pip:
pip install --upgrade mrscraper-sdkImport the client in your Python code:
from mrscraper import MrScraperAuthentication
The client reads your API token from the MRSCRAPER_API_TOKEN environment variable automatically. You can get your API token from the MrScraper dashboard.
export MRSCRAPER_API_TOKEN="MRSCRAPER_API_TOKEN"from mrscraper import MrScraper
client = MrScraper() # uses MRSCRAPER_API_TOKENYou can also pass the token explicitly:
client = MrScraper(token="MRSCRAPER_API_TOKEN")Custom HTTP client
Pass http_client= with your own httpx.AsyncClient to reuse connections across requests. Otherwise, the SDK creates a new client for each request.
import httpx
from mrscraper import MrScraper
async with httpx.AsyncClient() as http:
client = MrScraper(http_client=http)
result = await client.scraper_api("https://example.com")For more information on generating API tokens, see the Generate Token guide.
Quick Start
import asyncio
from mrscraper import MrScraper
async def main():
client = MrScraper()
# 1. Fetch page content
page = await client.scraper_api("https://example.com")
print(page["data"])
# 2. Search the web
search = await client.web_search("python web scraping", country="us")
print(search["data"]["data"])
# 3. Check remaining tokens
account = await client.account()
print(account["data"]["token_remaining"])
asyncio.run(main())Response Format
All methods return a dictionary with the same structure:
| Key | Type | Description |
|---|---|---|
status_code | integer | HTTP status code of the API response |
data | any | Python values for JSON responses, a string for text responses, or bytes for binary downloads |
headers | dict | Response headers |
Core Methods
Scraper API
Use scraper_api to fetch a page through the MrScraper Scraper API. The service handles JavaScript rendering, bot detection, and optional geolocation proxying.
import asyncio
from mrscraper import MrScraper
async def main():
client = MrScraper()
# HTML only (the default) returns the page as a string
page = await client.scraper_api("https://example.com/product")
print(page["data"])
# Markdown or a screenshot returns a dictionary with one entry per output
result = await client.scraper_api(
"https://example.com/product",
html=True,
markdown=True,
screenshot=True,
geo_code="US",
timeout=120,
)
print(result["data"]["markdown"])
asyncio.run(main())Requesting only HTML returns the page as a string. Requesting Markdown or a screenshot returns a dictionary with an entry for each requested output, such as html, markdown, and screenshot. At least one of html, markdown, or screenshot must be True.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Yes | - | Target page URL |
html | boolean | No | True | Return HTML content |
markdown | boolean | No | False | Return Markdown content |
timeout | integer | No | 120 | Page timeout in seconds (1-300) |
geo_code | string | No | "US" | Two-letter country code for geolocation (e.g., "US", "GB", "SG") |
proxy_country | string | No | None | Optional proxy country |
browser_rendering | boolean | No | None | True forces browser rendering, False disables it, None tries without a browser first and falls back automatically |
screenshot | boolean | No | False | Capture a screenshot. Also forces browser rendering |
super | boolean | No | False | Enable real device routing |
use_proxy | boolean | No | True | Allow the service to use a proxy |
proxy | string | No | None | Custom proxy in username:password@host:port format |
home_page | boolean | No | False | Visit the site's root page before the target URL |
wait_for_selector | string | No | None | CSS selector to wait for before returning content |
wait_until | string | No | None | Page lifecycle event to wait for, such as "domcontentloaded" |
block_resources | boolean | No | False | Block images, CSS, and fonts to speed up the request |
bypass_proxy | boolean | No | False | Load static assets such as images, fonts and stylesheets outside the residential proxy to save bandwidth |
cookie_jar | string | No | None | Cookie configuration, e.g. "domain=example.com&country=us&max_used=100&max_age=50m" |
headers | dict | string | No | None | Headers forwarded to the target site, as a dictionary or JSON string |
max_retries | integer | No | 3 | Maximum number of retries |
token_cap | integer | No | None | Optional token budget for retries |
stream | boolean | No | None | Request a streamed response. The SDK buffers it into the normal return value |
discard_token_secret | string | No | "" | Value sent in the x-discard-token-secret request header |
Tip
Setting screenshot=True always enables browser rendering, even if you pass browser_rendering=False.
For more examples of what you can fetch, see Scrape HTML, Scrape Markdown, and Get Screenshot.
Web Search
Use web_search to search the web and retrieve real-time search results, including relevant website URLs, titles, and descriptions. The first argument is the search query.
import asyncio
from mrscraper import MrScraper
async def main():
client = MrScraper()
result = await client.web_search(
"python web scraping",
country="us",
num_results=10,
)
for item in result["data"]["data"]:
print(item["rank"], item["title"], item["url"])
asyncio.run(main())The SDK sends this request:
curl --location 'https://api.mrscraper.com' \
--header 'x-api-token: {MRSCRAPER_API_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"action": "websearch",
"query": "python web scraping",
"country": "us",
"numResults": 10
}'Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | - | Search query. Must not be empty |
country | string | No | None | Country code for localized results, such as "us". Omitted to use the service default |
num_results | integer | No | 10 | Number of results, an integer from 10 to 100. Sent as numResults |
timeout | float | No | 600.0 | Request timeout in seconds |
Response (result["data"]):
| Key | Type | Description |
|---|---|---|
success | boolean | Whether the search succeeded |
message | string | Status message |
data | list | Ranked results. Each has rank, title, url, description, and source |
Account
Use account to check the identity, subscription, token quota, and rate limits of the account that owns the API token.
import asyncio
from mrscraper import MrScraper
async def main():
client = MrScraper()
result = await client.account(timeout=30)
print(result["data"]["subscription_status"])
print(result["data"]["token_remaining"])
print(result["data"]["user"]["email"])
asyncio.run(main())Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
timeout | float | No | 30.0 | Request timeout in seconds. Must be greater than 0 |
Account summary (result["data"]):
| Key | Type | Description |
|---|---|---|
subscription_status | string | None | Subscription status, such as "active" |
enterprise | boolean | Whether the account is on an enterprise plan |
token_usage | number | Tokens used in the current period |
token_limit | number | Token limit for the current period |
token_remaining | number | Remaining tokens, never below 0 |
usage_percent | number | Token usage as a percentage of the limit |
rate_limit | number | Request rate limit |
rate_ttl | number | Rate-limit window |
auto_renew | boolean | Whether the subscription renews automatically |
ends_at | string | None | Subscription end date |
user | dict | name, email, and verified |
Note
API keys, billing identifiers, and sensitive response headers are excluded from the result.
Error Handling
The SDK raises typed exceptions, which you can import from mrscraper or mrscraper.exceptions.
Exception Types
| Exception | When It's Raised |
|---|---|
MrScraperError | Base class for all SDK errors |
AuthenticationError | Missing or invalid API token (HTTP 401) |
APIError | Non-success API response (exposes .status_code) |
NetworkError | Network timeouts or connection failures |
Invalid arguments, such as a timeout outside 1-300 or a num_results outside 10-100, raise ValueError before any request is sent.
Example Error Handling
from mrscraper import MrScraper, AuthenticationError, APIError, NetworkError
client = MrScraper()
try:
result = await client.scraper_api("https://example.com")
except AuthenticationError:
print("Authentication failed. Check your API token at https://app.mrscraper.com")
except APIError as e:
print(f"API error {e.status_code}: {e}")
except NetworkError as e:
print(f"Network problem: {e}")Best Practices
- Always wrap SDK calls in try-except blocks
- Log errors with appropriate context for debugging
- Implement retry logic for
NetworkErrorexceptions - Verify your API token if you encounter
AuthenticationError
Migrating from Earlier Versions
From 0.7.x
Version 0.9.0 returns to three public methods. The 0.7.x format-specific methods are no longer public; use scraper_api with output flags instead:
| 0.7.x | 0.9.0 |
|---|---|
client.scraper_html(url) | client.scraper_api(url) |
client.scraper_markdown(url) | client.scraper_api(url, html=False, markdown=True) |
client.get_screenshot(url, full_page=False) | client.scraper_api(url, html=False, screenshot=True) |
client.web_search(query, region="us") | client.web_search(query, country="us") |
From 0.6.0
web_searchnow calls the MrScraper API withaction: "websearch"and returns JSON. Its first argument isquery, and it acceptscountryandnum_results(10 to 100). Theraw,format,region,language,page, andrender_jsoptions and search URL input were removed. Results are atresult["data"]["data"].scraper_apiadds thewait_untiloption. At least one ofhtml,markdown, orscreenshotmust beTrue. HTML-only requests return a string, and requests with Markdown or a screenshot return a dictionary with one entry per output.accountis unchanged.
From 0.5.0
Version 0.6.0 adds the account method. No existing methods changed.
From 0.4.0
Version 0.5.0 renames a public method. Arguments and response formats are unchanged.
| 0.4.0 | 0.5.0 |
|---|---|
client.fetch_content(...) | client.scraper_api(...) |
The previous method names have been removed.
From 0.3.x and Earlier
fetch_html and the AI scraper, manual scraper, results, and account methods (create_scraper, rerun_scraper, bulk_rerun_ai_scraper, rerun_manual_scraper, bulk_rerun_manual_scraper, get_all_results, get_result_by_id, get_analytic_statuses) are no longer part of the SDK. get_subscription_account is replaced by account.
- Replace
fetch_htmlwithscraper_api. It returns a dictionary withstatus_code,data, andheaders. - For scrapers, results, and analytics, call the REST API directly.
Migration from Firecrawl
If you're migrating from the Firecrawl Python SDK, use this mapping to find equivalent MrScraper methods.
| Firecrawl Method | MrScraper Equivalent |
|---|---|
| Scrape a URL with HTML or Markdown output | scraper_api with html=True and/or markdown=True |
| Scrape a URL with a screenshot | scraper_api with screenshot=True |
| Search | web_search |
Scalekit
Connect MrScraper MCP through Scalekit AgentKit to give your AI agents per-user web fetching, web search, and account usage tools.
Node.js SDK
Install the official @mrscraper/sdk package to fetch page content with the Scraper API and get real-time web search results from your Node.js applications.