API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com"
curl -L -x "http://YOUR_KEY:@proxy.zenrows.com:8001" -k "https://www.zenrows.com"

URL required

The URL is the page you want to scrape. It needs to be encoded.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com"
curl -L -x "http://YOUR_KEY:@proxy.zenrows.com:8001" -k "https://www.zenrows.com"

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

curl -H "Referrer: https://www.google.com" "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true"
curl -H "Referrer: https://www.google.com" -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.zenrows.com"

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont"
curl -L -x "http://YOUR_KEY:js_render=true&block_resources=image%2Cmedia%[email protected]:8001" -k "https://www.zenrows.com"

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080"
curl -L -x "http://YOUR_KEY:[email protected]s.com:8001" -k "https://www.zenrows.com"

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D"
curl -L -x "http://YOUR_KEY:css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%[email protected]:8001" -k "https://www.zenrows.com"

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

curl "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true"
curl -L -x "http://YOUR_KEY:[email protected]:8001" -k "https://www.amazon.com/dp/B01LD5GO7I/"

API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

ZenRows Python SDK comes with concurrency and error management built-in.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:@proxy.zenrows.com:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"

response = client.get(url)

print(response.text)

URL required

The URL is the page you want to scrape. It needs to be encoded.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:@proxy.zenrows.com:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"

response = client.get(url)

print(response.text)

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "js_render": "true"
}

response = client.get(url, params=params)

print(response.text)

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

# python3 and requests library required
# pip install requests
import requests
headers = {
	"Referrer": "https://www.google.com",
}
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true", headers=headers)
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
headers = {
	"Referrer": "https://www.google.com",
}
response = requests.get(url, proxies=proxies, verify=False, headers=headers)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
headers = {
	"Referrer": "https://www.google.com",
}

response = client.get(url, headers=headers)

print(response.text)

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "premium_proxy": "true"
}

response = client.get(url, params=params)

print(response.text)

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "premium_proxy": "true",
    "proxy_country": "us"
}

response = client.get(url, params=params)

print(response.text)

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "device": "desktop"
}

response = client.get(url, params=params)

print(response.text)

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "original_status": "true"
}

response = client.get(url, params=params)

print(response.text)

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "js_render": "true",
    "wait_for": ".content"
}

response = client.get(url, params=params)

print(response.text)

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "js_render": "true",
    "wait": 10000
}

response = client.get(url, params=params)

print(response.text)

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:js_render=true&block_resources=image%2Cmedia%[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "js_render": "true",
    "block_resources": "image,media,font"
}

response = client.get(url, params=params)

print(response.text)

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:[email protected]s.com:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "js_render": "true",
    "window_width": 1920,
    "window_height": 1080
}

response = client.get(url, params=params)

print(response.text)

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.zenrows.com"
proxy = "http://YOUR_KEY:css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.zenrows.com"
params = {
    "css_extractor": "{\"links\":\"a @href\", \"images\":\"img @src\"}"
}

response = client.get(url, params=params)

print(response.text)

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

# python3 and requests library required
# pip install requests
import requests
response = requests.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true")
print(response.text)
# python3 and requests library required
# pip install requests
import requests
url = "https://www.amazon.com/dp/B01LD5GO7I/"
proxy = "http://YOUR_KEY:[email protected]:8001"
proxies = {"http": proxy, "https": proxy}
response = requests.get(url, proxies=proxies, verify=False)
print(response.text)
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_KEY")
url = "https://www.amazon.com/dp/B01LD5GO7I/"
params = {
    "autoparse": "true"
}

response = client.get(url, params=params)

print(response.text)

API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

ZenRows Javascript SDK comes with concurrency and error management built-in.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:@proxy.zenrows.com:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, []);
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

URL required

The URL is the page you want to scrape. It needs to be encoded.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:@proxy.zenrows.com:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, []);
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "js_render": "true"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true", {
	headers: {
		"Referrer": "https://www.google.com",
	}
})
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent, headers: {
		"Referrer": "https://www.google.com",
	} })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";
	const headers = {
		"Referrer": "https://www.google.com",
	};

    try {
        const { data } = await client.get(url, {
    "custom_headers": "true"
}, { headers });
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "premium_proxy": "true"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "premium_proxy": "true",
    "proxy_country": "us"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "device": "desktop"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "original_status": "true"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "js_render": "true",
    "wait_for": ".content"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "js_render": "true",
    "wait": 10000
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:js_render=true&block_resources=image%2Cmedia%[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "js_render": "true",
    "block_resources": "image,media,font"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:[email protected]s.com:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "js_render": "true",
    "window_width": 1920,
    "window_height": 1080
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.zenrows.com";
const proxy = "http://YOUR_KEY:css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.zenrows.com";

    try {
        const { data } = await client.get(url, {
    "css_extractor": "{\"links\":\"a @href\", \"images\":\"img @src\"}"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

// npm install axios
const axios = require("axios");

axios.get("https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true")
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install axios http-proxy-agent https-proxy-agent
const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.amazon.com/dp/B01LD5GO7I/";
const proxy = "http://YOUR_KEY:[email protected]:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios
    .get(url, { httpAgent, httpsAgent })
    .then(response => console.log(response.data))
    .catch(error => console.log(error));
// npm install zenrows
const { ZenRows } = require("zenrows");

(async () => {
    const client = new ZenRows("YOUR_KEY");
    const url = "https://www.amazon.com/dp/B01LD5GO7I/";

    try {
        const { data } = await client.get(url, {
    "autoparse": "true"
});
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

URL required

The URL is the page you want to scrape. It needs to be encoded.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
		conn.setRequestProperty("Content-Type", "application/json");
		conn.setRequestProperty("Referrer", "https://www.google.com");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestProperty("Content-Type", "application/json");
		conn.setRequestProperty("Referrer", "https://www.google.com");
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.zenrows.com");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

public static String getRequest() {
    try {
        String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true";
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}
public static String proxyRequest() {
    try {
        URL url = new URL("https://www.amazon.com/dp/B01LD5GO7I/");
        Properties props = System.getProperties();
        props.setProperty("http.proxyHost", "http://proxy.zenrows.com");
        props.setProperty("http.proxyPort", "8001");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();  
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuffer content = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                content.append(line);
            }
            in.close();
            return content.toString();
        } else {
            throw new Exception("Error in API Call");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:@proxy.zenrows.com:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

URL required

The URL is the page you want to scrape. It needs to be encoded.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:@proxy.zenrows.com:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
	'Referrer: https://www.google.com',
]);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
	'Referrer: https://www.google.com',
]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:js_render=true&block_resources=image%2Cmedia%[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]s.com:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.zenrows.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>
<?php
$url = 'https://www.amazon.com/dp/B01LD5GO7I/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, 'http://YOUR_KEY:[email protected]:8001');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
echo $response . PHP_EOL;
curl_close($ch);
?>

API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:@proxy.zenrows.com:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

URL required

The URL is the page you want to scrape. It needs to be encoded.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:@proxy.zenrows.com:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true", nil)
	req.Header.Add("Referrer", "https://www.google.com")
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
	req.Header.Add("Referrer", "https://www.google.com")
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:js_render=true&block_resources=image%2Cmedia%[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]s.com:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.zenrows.com"
    proxy, _ := url.Parse("http://YOUR_KEY:css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true", nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}
package main

import (
    "crypto/tls"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    inputUrl := "https://www.amazon.com/dp/B01LD5GO7I/"
    proxy, _ := url.Parse("http://YOUR_KEY:[email protected]:8001")
    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            Proxy:           http.ProxyURL(proxy),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        },
    }

    req, err := http.NewRequest("GET", inputUrl, nil)
    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatalln(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }

    log.Println(string(body))
}

API Documentation

ZenRows API makes scraping a breeze. There are three methods in which you can send requests to ZenRows:

  • Via our API endpoint https://api.zenrows.com/v1/?apikey=APIKEY
  • Via our Proxy Server https://APIKEY@proxy.zenrows.com:8001
  • Via our Node or Python SDKs

Only two parameters that are required to get started with ZenRows API: apikey and url to start using the API.

API Key required

To access API functionality, you need to have a valid API Key. This unique key will keep all your requests authorized.

Start using the API by creating your API Key now.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:@proxy.zenrows.com:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

URL required

The URL is the page you want to scrape. It needs to be encoded.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:@proxy.zenrows.com:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Custom Parameters

Here is a complete list of parameters you can use to customize your requests.

parameter type default description
apikey required string Get Your Free API Key learn more
url required string http://example.com/ The URL you want to scrape learn more
js_render boolean false Render the Javascript on the page with a headless browser (5 credits/request) learn more
custom_headers boolean false Enable custom headers to be passed to the request. learn more
premium_proxy boolean false Use premium proxies to make the request harder to detect (10-25 credits/request) learn more
proxy_country string "" Geolocation of the IP used to make the request. Only for Premium Proxies. learn more
device string "" Use either desktop or mobile user agents in the headers. learn more
original_status boolean false Returns the status code provided by the website. learn more
wait_for string "" Wait for a given CSS Selector to load in the DOM before returning the content. learn more
wait integer 0 Wait a fixed amount of time before returning the content. learn more
block_resources string "" Block specific resources from loading using this parameter. learn more
window_width integer 1920 Set browser's window width. learn more
window_height integer 1080 Set browser's window height. learn more
css_extractor string (JSON) "" Define CSS Selectors to extract data from the HTML. learn more
autoparse boolean false Use our auto parser algorithm to automatically extract data. learn more

Javascript Rendering

Some websites rely heavily on Javascript to load content. Enable this feature if you need to extract data that are loaded dynamically.

You can enable Javascript by adding &js_render=true to the request. This request costs 5 credits.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Custom Headers

Custom Headers come in handy when you need to add your own headers (user agents, cookies, referrer, etc.) to the request.

You can enable Custom Headers by adding &custom_headers=true to the request.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&custom_headers=true')
headers = {
	"Referrer": "https://www.google.com",
}
res = Net::HTTP.get(url, headers)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
headers = {
	"Referrer": "https://www.google.com",
}
conn = Faraday.new(proxy: proxy, ssl: {verify: false}, headers: headers) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Premium Proxies

Some websites are harder to scrape and block datacenter IPs. Premium Proxies come in handy to solve this problem. As the name suggests, these proxies come straight from ISP providers.

You can easily use Premium Proxies adding &premium_proxy=true to the request. This request costs 10 credits.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Geolocation

Some content is specific to a region. In these cases, you may want to make your request from a given country.

You only need to add &premium_proxy=true&proxy_country=us to the request. Geolocation requires Premium Proxies enabled (it costs 10-25 credits).

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&premium_proxy=true&proxy_country=us')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Device

If you require to use either desktop or mobile user agents in the headers, you can use &device=desktop or &device=mobile parameter in the request.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&device=desktop')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Original HTTP Code

ZenRows API returns HTTP Codes depending on the result of the request. If you want to return the status code provided by the website, enable &original_status=true

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&original_status=true')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Headless: Wait For Selector

Sometimes you may want to wait for a given CSS Selector to load in the DOM before ZenRows returns the content. You can get this behaviour by adding &wait_for=.background-load parameter into the request.

Requires javascript rendering (&js_render=true).

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait_for=.content')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Headless: Wait Milliseconds

Some websites take a lot time to load. If you need to wait a fixed amount of time until everything is loaded, you can define the time in milliseconds with &wait=10000 parameter, which will wait 10000 milliseconds (10 seconds) before returning the HTML.

Requires javascript rendering (&js_render=true).

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&wait=10000')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Headless: Block Resources

Many websites load dozens of resources delaying the HTML response. You can block specific resources from loading using &block_resources=image parameter.

ZenRows API allows to block the following resources: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. Separate by commas to block multiple resources.

Requires javascript rendering (&js_render=true).

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&block_resources=image%2Cmedia%2Cfont')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:js_render=true&block_resources=image%2Cmedia%[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Headless: Window Width/Height

If you need to change the browser's window width and height, you can the &window_width=1920 and &window_height=1080 parameters.

Requires javascript rendering (&js_render=true).

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&js_render=true&window_width=1920&window_height=1080')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:[email protected]s.com:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Data Extraction: CSS Selectors

You can use CSS Selectors for data extraction. In the table below, you will find a list of examples of how to use it.

You only need to add &css_extractor={"links":"a @href"} to the request to use this feature.

Here are some examples

extraction rules sample html value json output
{"divs":"div"} <div>text0</div> text {"divs": "text0"}
{"divs":"div"} <div>text1</div><div>text2</div> text {"divs": ["text1", "text2"]}
{"links":"a @href"} <a href="#register">Register</a> href attribute {"links": "#register"}
{"hidden":"input[type=hidden] @value"} <input type="hidden" name="_token" value="f23g23g.b9u1bg91g.zv97" /> value attribute {"hidden": "f23g23g.b9u1bg91g.zv97"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"class":"button.submit @data-v"} <button class="submit" data-v="register-user">click</button> data-v attribute with submit class {"class": "register-user"}
{"emails":"a[href^='mailto:'] @href"} <a href="mailto:[email protected]">email 1</a><a href="mailto:[email protected]">email 2</a> href attribute for links starting with mailto: {"emails": ["[email protected]", "[email protected]"]}

If you are interested in learning more, you can find a complete reference of CSS Selectors here.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.zenrows.com&css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%7D')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.zenrows.com'
proxy = 'http://YOUR_KEY:css_extractor=%7B%22links%22%3A%22a%20%40href%22%2C%20%22images%22%3A%22img%20%40src%22%[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)

Data Extraction: Auto Parsing

ZenRows API will return the HTML of the URL by default. Enabling Autoparse uses our extraction algorithms to parse data in JSON format automatically.

Add &autoparse=true to the request for this feature.

require 'net/http'
url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_KEY&url=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB01LD5GO7I%2F&autoparse=true')
res = Net::HTTP.get(url)
print(res)
# gem install faraday faraday_middleware
require 'faraday'
require 'faraday_middleware'

url = 'https://www.amazon.com/dp/B01LD5GO7I/'
proxy = 'http://YOUR_KEY:[email protected]:8001'
conn = Faraday.new(proxy: proxy, ssl: {verify: false}) do |faraday |
    faraday.use FaradayMiddleware::FollowRedirects
    faraday.adapter Faraday.default_adapter
end
res = conn.get(url)
print(res.body)