Migrating from ZenRows to Zyte API#
Learn how to migrate from ZenRows to Zyte API.
Feature comparison#
The following table summarizes the feature differences between both products:
Feature |
Zyte API |
ZenRows |
---|---|---|
API |
HTTP |
|
Client software |
Python, NodeJS |
|
Restricted website categories |
None |
Banks, payment gateways, visas/permits, government |
Always available, automatic |
Only Business+, manual |
|
AI-powered, standard schemas, supports crawling |
Undocumented website support, item type support or output schema |
|
Markdown output |
No |
Yes |
249 countries, data center support |
190 countries, no data center support |
|
Client-managed (15m) and server-managed |
Client-managed only (10m), no cookies |
|
Basic (15), advanced, website-specific and custom |
Basic only (10) |
|
JPEG/PNG, configurable viewport, cannot target element |
PNG only, fixed viewport, can target element |
|
Up to 5 MiB / 10 responses |
Unlimited |
|
Network blocking |
No |
Yes |
Yes |
No |
|
Server-side CSS selectors |
No |
Yes |
RPM-based |
Concurrency-based |
|
Rate-limiting responses |
Rate-limiting responses followed by IP blocking |
Automatic extraction#
ZenRows supports automatic extraction, but their documentation does not provide details on supported websites, item types or output schemas.
Zyte API automatic extraction is AI-based, i.e. it works on any website of a supported type (e.g. e-commerce, blogs/news, job postings), and we provide detailed documentation about output schemas. It also supports automatic crawling.
Sessions#
ZenRows only supports client-managed sessions, and limits them to 10 minutes. Moreover, their sessions do not maintain cookies, you must do that on the client side.
Zyte API allows 15 minutes for client-managed sessions, but also supports server-managed sessions with much longer lifetimes and an easier API. Moreover, the Scrapy plugin supports an additional session management API.
Screenshots#
Both ZenRows and Zyte API support PNG screenshots of the visible viewport or the full page.
ZenRows allows taking a screenshot of a specific element.
Zyte API allows configuring the browser viewport.
Zyte API can return both browserHtml and screenshot on the same request, i.e. get the browser HTML matching a given screenshot. In ZenRows you would need 2 separate requests, and the contents of each might not be a perfect match.
Rate limiting#
ZenRows limits the number of concurrent requests that you can send, starting at 10 with the most basic plan.
Zyte API limits the number of requests per minute (RPM) that you can send. It is 500 by default for all Zyte API keys, but you can get a higher limit for free.
For services like these that support advanced features like browser rendering or automatic extraction, which usually increase response times, RPM rate limiting allows you to maintain your throughput regardless of which features you use thanks to unlimited concurrency, while concurrency-based limits slow down your crawls as you use features that make requests slower.
For example, assuming an HTTP request takes 2 seconds and a browser request takes 20 seconds, switching from HTTP requests to browser requests with ZenRows would make your crawl 10 times slower, while Zyte API would allow you to maintain a similar crawl speed by using more concurrent requests to make up for the response time increase.
Overuse handling#
When you exceed your concurrency with ZenRows, they start by sending rate-limiting responses, but eventually they block your IP address for increasing amounts of time.
With Zyte API, reaching your rate limit is not only allowed, but encouraged, and you can request a higher RPM limit for free if you need it.
Migrating#
The main differences between the HTTP APIs of ZenRows and Zyte API are how request parameters are defined and how the response is encoded.
In ZenRows, you send a GET
request, and you specify parameters in the
URL query string, URL-encoded, e.g.
curl "https://api.zenrows.com/v1/?apikey=YOUR_API_KEY&url=https%3A%2F%2Ftoscrape.com"
The API response body comes straight from the target website:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Scraping Sandbox</title>
…
HTTP response headers from the target website are also received as regular
headers, only prefixed with Zr-
, and the response URL (which might not
match the request URL, e.g. in case of redirection) is received as the special Zr-Final-Url
header:
Zr-Content-Encoding: br
Zr-Content-Type: text/html
Zr-Final-Url: https://toscrape.com/
In Zyte API, you send a POST
request, and you specify parameters in the
request body as JSON, e.g.
curl \
--user YOUR_API_KEY: \
--header 'Content-Type: application/json' \
--data '{"url": "https://toscrape.com", "httpResponseBody": true, "httpResponseHeaders": true}' \
--compressed \
https://api.zyte.com/v1/extract
The API response is a JSON object with all the response data from the target website:
{
"url": "https://toscrape.com/",
"statusCode": 200,
"httpResponseBody": "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICAgIDx…",
"httpResponseHeaders": [
{
"name": "content-type",
"value": "text/html"
},
{
"name": "content-encoding",
"value": "br"
}
]
}
Note
httpResponseBody is base64-encoded to support binary responses, like images or PDF files.
Once you understand how to migrate a simple request like the one above, you can migrate any other request the same way, replacing ZenRows parameters with Zyte API counterparts.
Parameter mapping#
ZenRows |
Zyte API |
---|---|
(default) |
|
|
|
|
|
|
|
|
|
|
ipType=residential (not required to avoid bans) |
|
geolocation (does not require ipType=residential) |
|
session.id (must be UUID4) |
|
|
|
N/A (see statusCode) |
|
N/A (see Bad website responses) |
|
Not supported |
|
See Network capture |
|
Not supported |
|
|
|
Not supported |
|
|
|
|
|
Not supported |
For parameters defining browser actions, see Action mapping.
Action mapping#
check
: click
click
: click
evaluate
: evaluate
fill
: type
scroll_x
: scrollTo
scroll_y
: scrollTo
select_option
: select
uncheck
: click
wait
: waitForTimeout
wait_for
: waitForSelector
wait_for
only supports CSS selectors, while waitForSelector
also
supports XPath selectors.
ZenRows also has a solve_captcha
action that requires you to specify which
CAPTCHA you need to solve, while Zyte API avoids bans automatically, no action necessary.
doubleClick
goto
hide
hover
keyPress
reload
scrollBottom
searchKeyword
setLocation
waitForNavigation
waitForRequest
waitForResponse
Zyte API also supports custom actions.
ZenRows actions have frame_
-prefixed counterparts that work on iframes,
and a utility action (frame_reveal
) to inject iframe contents into the
main DOM. On Zyte API you need to use custom actions
to interact with iframes.