ScrapingBee Alternatives: Cost per Rendered Page and the Proxy Route

ZenRows, ScraperAPI, Zyte API and Firecrawl compared with ScrapingBee on what a rendered page costs in credits, and when your own scraper and proxies fit.

ScrapingBee sells a credit-metered HTML API. The plan price buys a block of credits, and how many pages those credits fetch depends on which features each request switches on. That is the number worth comparing when you look at alternatives: not the plan price, and not the headline credit count, but what one rendered page costs on the request you actually send. This page works that out for ScrapingBee, ZenRows, ScraperAPI, Zyte API and Firecrawl, then covers the other kind of alternative, running your own scraper through proxies. The ZenRows alternatives guide explains the API-or-proxies split in general; this one stays on the arithmetic.

Vendor figures were checked October 19, 2026, on each vendor's own pricing page or documentation. Nothing was benchmarked, so this page compares billing, not output quality.

How ScrapingBee bills

The entry plans are $19 a month for 75,000 credits and 25 concurrent requests on the Hobby plan and $49 a month for 250,000 credits and 50 concurrent requests on the Freelance plan, with prices listed before VAT. New accounts get 1,000 free API credits with no card, and paid plans carry credits valid for one month, with no rollover.

Each request then draws on that balance by weight: 1 credit without JavaScript rendering, 5 with it, the default; 10 or 25 with premium proxies; 75 with stealth proxies and rendering. Two details in that line change the arithmetic more than any plan choice:

Billing on failure is also specific: by default a target's 403 or 503 reaches you as a 500, and a 500 from ScrapingBee is not billed. Asking for the target's own status code changes that, because every answer below 500 is then billed. Beyond plain HTML the API has an option that returns the page's main content as Markdown, screenshots of the viewport, the full page or one element picked by CSS selector, and an option to use its features with your own proxy provider.

ScrapingBee and its alternatives side by side

The first five rows are managed scraping APIs that render and route for you. The last row is a proxy service, which leaves rendering to your own code.

OptionEntry planCredit weightsWhat is not billed
ScrapingBee$19 a month for 75,000 credits and 25 concurrent requests on the Hobby plan1 credit without JavaScript rendering, 5 with it, the default; 10 or 25 with premium proxies; 75 with stealth proxies and renderingby default a target's 403 or 503 reaches you as a 500, and a 500 from ScrapingBee is not billed
ZenRows$19 a month for 45,000 credits on the Build plan1 credit for a standard page, 5 with JavaScript rendering, 10 with premium proxies and 25 with bothfailed requests never charged, with 404 and 410 answers counted as results
ScraperAPI$49 a month for 100,000 credits and 20 concurrent threads on the Hobby plan, with geotargeting in the US and EU only10 credits for a rendered request, 25 with premium proxies and rendering, and 75 with ultra-premium proxies and renderingcharges only for responses with status 200 or 404, and for requests you cancel before about 70 seconds; everything else is free
Zyte APIPer-response pricing rather than a credit plan5 cost tiers each for HTTP and browser requests, assigned per target websitecharges only for successful responses, with rate-limited and unsuccessful responses free
Firecrawl$19 a month billed monthly, or $16 a month billed annually, for 5,000 credits1 credit per page on a basic scrape, crawl or map, plus 4 credits a page for the JSON, Question and Highlight formatsno charge for a scrape that returns no result, while a page that answers 403 or 404 is returned and costs 1 credit
Node4Rotating Unmetered 250 connections, $29.00 a month; Rotating Datacenter 10 GB, $5.90 a month; residential 3 GB, $7.47 a monthNone: you pay for connections or gigabytes, and rendering runs in your own browserNothing is billed per page; traffic or connections are billed whether or not the target answered

ScraperAPI's weights are per parameter, and some domains carry their own credit cost, such as Google and Bing at 25 credits a request. ZenRows' Build figure is its monthly-billing price from the API docs; its pricing page defaults to annual billing and shows a lower monthly number.

What a rendered page costs on each entry plan

Take a workload where every page needs JavaScript rendering and some share also needs premium routing. Divide each plan's credits by the weight of that request, and you get the most pages the plan can fetch if every request is that kind:

PlanCreditsRendered pagesRendered with premium proxies
ScrapingBee Hobby75,00015,000 at 5 credits3,000 at 25 credits
ScrapingBee Freelance250,00050,000 at 5 credits10,000 at 25 credits
ZenRows Build45,0009,000 at 5 credits1,800 at 25 credits
ScraperAPI Hobby100,00010,000 at 10 credits4,000 at 25 credits
Firecrawl Hobby5,0005,000 at 1 credit on a basic scrapeNo premium weight on its pricing page

Then divide the plan price by the page count to get a cost per rendered page, which is the figure to put side by side. Three things move it once real traffic starts:

Zyte API is missing from the table because its price per response depends on the tier it assigns to each site, so the only honest figure comes from sending your own URLs through it. For a per-request view of proxies against APIs, the per-request cost guide does the same division from the proxy side.

When your own scraper with proxies is the better alternative

A proxy service is a different purchase: you buy exits and run the browser yourself, so rendering or a hard target does not multiply a per-request price. It still costs something: a rendered page downloads scripts and images and holds a connection longer, which shows up on a per-gigabyte or per-connection plan. It tends to fit when one of these is true:

Node4 sells three products for this. Rotating Unmetered has no byte meter and is priced by how many connections you hold open at once, from $29.00/month for 250 connections ($0.116 per connection) on the unmetered pricing page. Rotating Datacenter draws from the same pool and is billed by the gigabyte, from $5.90/month for 10 GB ($0.59/GB). Residential proxies cover sites that refuse datacenter addresses, from $7.47/month for 3 GB ($2.49/GB). The rotating gateway picks an exit from the pool for each HTTPS tunnel or plain-HTTP request, and a session id holds one exit for up to 30 minutes. Node4 adds no rendering, extraction or retry layer, and its datacenter exits are in the US, Italy and Spain.

Before switching, measure how much of your target list works without a browser at all. This script fetches a list of URLs through the gateway and sorts the answers by what a plain HTTP client actually received:

import os
import sys
from collections import Counter
from html.parser import HTMLParser

import requests

PROXY = (
    "http://" + os.environ["NODE4_USER"] + ":" + os.environ["NODE4_PASS"]
    + "@gw-rotating_datacenter.node4.io:8083"
)
MIN_WORDS = int(os.environ.get("MIN_WORDS", "150"))     # set per site
EXPECT = os.environ.get("EXPECT_TEXT", "").lower()      # text every good page has
REFUSAL_HINTS = ("verify you are human", "access denied", "unusual traffic", "request blocked")
GATE_HINTS = ("accept all cookies", "sign in to continue", "log in to continue")

class VisibleText(HTMLParser):
    """Text a reader would see, from <main>/<article> when the page has one."""
    SKIP = {"script", "style", "noscript", "template", "svg"}

    def __init__(self):
        super().__init__()
        self.skip = self.depth = 0
        self.has_main = False
        self.body, self.main = [], []

    def handle_starttag(self, tag, attrs):
        if tag in self.SKIP:
            self.skip += 1
        if tag in ("main", "article"):
            self.depth += 1
            self.has_main = True

    def handle_endtag(self, tag):
        if tag in self.SKIP and self.skip:
            self.skip -= 1
        if tag in ("main", "article") and self.depth:
            self.depth -= 1

    def handle_data(self, data):
        if not self.skip:
            (self.main if self.depth else self.body).append(data)

def classify(r: requests.Response) -> str:
    if r.status_code in (401, 403, 407, 429, 451):
        return "refused"
    if r.status_code != 200:
        return "other_status"
    page = VisibleText()
    page.feed(r.text)
    text = " ".join(page.main if page.has_main else page.body).lower()
    if any(h in text[:2000] for h in REFUSAL_HINTS):
        return "refused"
    if any(h in text[:2000] for h in GATE_HINTS) or "/login" in r.url or "/signin" in r.url:
        return "consent_or_login"
    if (EXPECT and EXPECT in text) or (not EXPECT and len(text.split()) >= MIN_WORDS):
        return "static_candidate"
    return "thin_needs_review"

counts = Counter()
for url in (line.strip() for line in open(sys.argv[1]) if line.strip()):
    try:
        r = requests.get(url, proxies={"http": PROXY, "https": PROXY}, timeout=30)
        label = classify(r)
    except requests.RequestException:
        label = "network_error"
    counts[label] += 1
    print(label, url, sep="\t")
print(dict(counts))

The page size alone says nothing: a JavaScript shell can be 9,000 characters of script around an empty <main>. So the script counts the words a reader would see, inside <main> or <article> when the page has one, and labels each URL:

The phrase lists are examples, not a complete detector; add the wording your targets use. Run it on a few hundred real URLs. A high static_candidate share suggests your own scraper through proxies covers most of the job. A high thin_needs_review share that survives a closer look means you would be running a browser for those pages, and one of the APIs above may cost less than the engineering time. A high refusal share is a question about rate, address type and the site's terms before it is a question about rendering.

There is also a middle path: ScrapingBee keeps its rendering and extraction features when you bring your own proxies. Check how such requests are billed on your plan before planning around it. The scraping API vs proxies guide works through that trade-off in more detail.

The decision

Stay with ScrapingBee if the rendered weight fits your budget and you can switch rendering off for static targets. Look at ZenRows if its weights suit a premium-heavy mix, at ScraperAPI once you have checked its per-domain costs for your targets, at Zyte API if you want to pay per successful response at a site-specific rate, and at Firecrawl if your pages are mostly simple and you want Markdown-first output. Move to your own scraper with Node4 proxies when most pages work without a browser or the volume makes a per-page price the largest line in the budget. The Firecrawl alternatives and Jina Reader alternatives guides cover the Markdown-first services in more depth.

Node4's Scrape API, in development

Node4 is building a Scrape API that will render a page and return HTML, Markdown or a screenshot from one request. It is not available yet, and it has no published price or launch date; the waitlist is open for anyone who wants to hear when it opens. The proxy products above are what Node4 sells today.