GridPanel has one API you can use:
Below you will find information on how to use and make the most out of these APIs yourself.
All requests, except when explicitly mentioned, to both GridPanel APIs are authenticated using your private API key.
To get access to your API key, create an account and confirm your email address. You can do this here
Get information about the user this API key belongs to.
curl 'https://gridpanel.net/api/user?api_key=API_KEY'
import requests
params = {
'api_key': 'API_KEY',
}
response = requests.get('https://gridpanel.net/api/user', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/user')
params = {
:api_key => 'API_KEY',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/user?api_key=API_KEY", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/user?api_key=API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/user?api_key=API_KEY"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/user?api_key=API_KEY');
{
"user": {
"first_name": "Bob",
"last_name": "Marley",
"email": "[email protected]",
"gbp_balance_in_pence": 10000
}
}
Our mobile proxy API enables you to: rotate your proxies, get information regarding your usage and your orders in general.
Please note, in order to use the proxy endpoints below, you will need to have an active proxy order on your account.
You can order your GridPanel mobile proxies here.
This endpoint allows you to rotate the IP of your mobile proxy.
Please note that this endpoint does not require your api_key as a parameter.
When you call this endpoint, it will take your proxy down for 20-40 seconds in order for us to get you a new IP address. This is because rotation involves taking the device offline then online again in quick succession. If you have a 5G proxy, it will take your proxy down for around 5-10 seconds as the process is much faster here.
name [type] (default_value) | Description |
---|---|
token [string] (required) |
This is your rotation token, you will be given one per order and can find it on your manage order page.
|
curl 'https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi'
import requests
params = {
'token': 'MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi',
}
response = requests.get('https://gridpanel.net/api/reboot', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/reboot')
params = {
:token => 'MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi');
In the case of a successful rotation you will receive the following response.
{
"success": true
}
If you attempt to rotate to frequently, in that you rotate faster than you orders minimum rotation time, you will receive the following response.
{
"success": false,
"reason": "too_frequent"
}
Get all proxy orders in your account
curl 'https://gridpanel.net/api/proxies?api_key=API_KEY'
import requests
params = {
'api_key': 'API_KEY',
}
response = requests.get('https://gridpanel.net/api/proxies', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/proxies')
params = {
:api_key => 'API_KEY',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/proxies?api_key=API_KEY", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/proxies?api_key=API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/proxies?api_key=API_KEY"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/proxies?api_key=API_KEY');
{
"orders": {
"10123": {
"port": 10123,
"status": "active",
"expiry_date": "2023-03-30T00:00:00Z",
"plan": "5G Mobile Proxies",
"duration": "Monthly",
"auto_renew": true,
"auto_rotate": false,
"auto_rotate_seconds": null,
"last_reboot": "2023-03-04T12:34:56Z",
"minimum_rotation_time_seconds": 300,
"gateway_ip": "192.168.1.1",
"username": "username",
"password": "password",
"reboot_url": "https://gridpanel.net/api/reboot?token=1234",
"reboot_token": "1234",
"connection_string": "username:[email protected]:10123",
"network": "THREE",
"location": "LONDON",
},
"10124": {
"port": 10124,
"status": "active",
"expiry_date": "2023-03-30T00:00:00Z",
"plan": "4G Mobile Proxies",
"duration": "Monthly",
"auto_renew": true,
"auto_rotate": false,
"auto_rotate_seconds": null,
"last_reboot": "2023-03-06T12:00:00Z",
"minimum_rotation_time_seconds": 300,
"gateway_ip": "192.168.1.1",
"username": "username",
"password": "password",
"reboot_url": "https://gridpanel.net/api/reboot?token=1235",
"reboot_token": "1235",
"connection_string": "username:[email protected]:10124",
"network": "EE",
"location": "LONDON",
}
}
}
Returns daily statistics (such as bandwidth usage) for one or more proxies, across a date range.
name [type] (default_value) | Description |
---|---|
ports [string] (required) |
Proxy port(s) to query for (comma-separated) e.g. 10123,10124
|
start [string] (required) |
Date to query from in YYYY-MM-DD format e.g. 2023-01-01
|
end [string] (required) |
Date to query to in YYYY-MM-DD format e.g. 2023-01-01. Must be within 31 days of start but more than 48 hours before the time of request.
|
curl 'https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04'
import requests
response = requests.get(
'https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04',
)
require 'net/http'
uri = URI('https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04')
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04');
{
"results": {
"10123": [
{
"date": "2023-03-04",
"used_bytes": 11111111111
},
{
"date": "2023-03-03",
"used_bytes": 22222222222
},
{
"date": "2023-03-02",
"used_bytes": 33333333333
},
{
"date": "2023-03-01",
"used_bytes": 44444444444
}
],
"10124": [
{
"date": "2023-03-04",
"used_bytes": 55555555555
},
{
"date": "2023-03-03",
"used_bytes": 66666666666
},
{
"date": "2023-03-02",
"used_bytes": 77777777777
},
{
"date": "2023-03-01",
"used_bytes": 88888888888
}
]
}
}
Our anti-detect API enables you to automatically manage your browser profiles from custom sotware. This means you can create, start, stop and manage profiles entirely automatically. You can then connect to them using your favourite browser automation framework.
In order to connect to favourite automation software, you will need to get the automation endpoint from inside the running profiles. This is available via the Settings button from within a running browser session.
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:53018")
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get('http://iphey.com')
Remember to replace 127.0.0.1:53018 with your endpoint.
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.connect({
browserURL: `http://127.0.0.1:53018`
});
const page = await browser.newPage();
await page.goto('http://iphey.com');
})();
Remember to replace 127.0.0.1:53018 with your endpoint.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.connectOverCDP(`http://127.0.0.1:53018`);
const page = await browser.contexts()[0].newPage();
await page.goto('https://iphey.com');
})();
Remember to replace 127.0.0.1:53018 with your endpoint.
For the ultimate control, we highly recommend connecting directly via CDP (the Chrome Devtools Protocol). This provides the lowest risk of being caught with an automation framework, but provides the most raw access and the least number of in-built features.
To use CDP, you can begin by opening http://127.0.0.1:53018/json to see your tabs. Explore the https://chromedevtools.github.io/devtools-protocol/ to see how to control each part of the browser, much like how you would with Selenium, Playwright or Puppeteer.
Remember to replace 127.0.0.1:53018 with your endpoint.
GridPanel's scraping API is the easiest scraping API available to use on the web.
To scrape any web page, you need two things:
The following is an example snippet of a simple
GET
API call to scrape the URL defined in the query string
variable
YOUR-URL
:
curl 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL'
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL');
The API will then respond with the raw HTML content of the target URL:
<html>
<head>
...
</head>
<body>
...
</body>
</html>
Be aware of the maximum 30-second timeout when your code calls the API
Headers and cookies returned by the target website are prefixed with
Spb-
(for Scraping browser)
Here is the list of the different parameters you can use with GridPanel's HTML API.
name [type] (default_value) | Description |
---|---|
api_key [string] (required) |
Your API key Get your API key
|
url [string] (required) |
The URL of the page you want to scrape
|
render_js [boolean] (true) |
Render javascript on the page
|
block_ads [boolean] (false) |
Block ads on the page you want to scrape
|
block_resources [boolean] (true) |
Block images and CSS on the page you want to
scrape
|
cookies [string] ("") |
Pass custom cookies to the webpage you want to
scrape
|
country_code [string] ("") |
Premium proxy geolocation
|
device [string] ("desktop") |
Control the device the request will be sent
from
|
extract_rules [[stringified JSON]] ("") |
Data extraction from CSS selectors
|
forward_headers [boolean] (false) |
Forward particular headers to the webpage,
as well as any other headers generated by GridPanel
|
forward_headers_pure [boolean] (false) |
Forward only particular headers to
webpage, no other headers
|
js_scenario [[stringified JSON]] ({}) |
JavaScript scenario to execute
|
json_response [bool] (false) |
Wrap the response in JSON
|
own_proxy [string] ("") |
The details of your own proxy, if you want to use your own.
|
return_page_source [boolean] (false) |
Return the original HTML before JavaScript rendering
|
screenshot [boolean] (false) |
Return a screenshot of the page you want to scrape
|
screenshot_selector [string] ("") |
Return a screenshot of a certain area of the page, based on a CSS selector
|
create_session [boolean] (false) |
Create a session that lasts 5 minutes
|
session_id [string] ("") |
Route multiple API requests through the same session (IP address and browser context)
|
stealth_proxy [boolean] (false) |
Use special stealth proxy pool
|
timeout [integer] (14000) |
Timeout for your requests
|
transparent_status_code [boolean] (false) |
Transparently return the same HTTP code of the page requested
|
wait [integer] (0) |
Additional time in ms for JavaScript to render
|
wait_browser [string] (domcontentloaded) |
Wait until certain browser conditions are met before returning the response
|
wait_for [string] ("") |
CSS/XPath selector to wait for in the DOM
|
window_height [integer] (1080) |
Pixel height of the viewport used to render the page you want to scrape
|
window_width [integer] (1920) |
Pixel width of the viewport used to render the page you want to scrape
|
This parameter is the full URL including the protocol (with
http/https
) of the page to extract data from.
You must encode your URL. For example, the
+
character is encoded to
%20
. Consult your programming language documentation for functions that encode URLs.
Alternatively you can encode/decode urls using this tool: https://meyerweb.com/eric/tools/dencoder/
We have provided a number of examples for some languages below:
p = URI::Parser.new
p.escape("YOUR-URL")
sudo apt-get install gridsite-clients
urlencode "YOUR URL"
import urllib.parse
encoded_url = urllib.parse.quote("YOUR URL")
<?php
$url_encoded = urlencode("YOUR URL");
?>
String encoded_url = URLEncoder.encode("YOUR URL", "UTF-8");
package main
import (
"net/url"
)
func main() {
encoded_url := url.QueryEscape("YOUR URL")
}
encoded_url = encodeURIComponent("YOUR URL")
By default, GridPanel will fetch the URL you want to scrape on a real device and execute the websites JavaScript code on the page.
However, there may be scenarios where you want to disable JS rendering entirely, this can be done by setting render_js=false, like we are doing below:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'render_js': 'false',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:render_js => 'false',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false');
To block ads when scraping pass block_ads=true, this can also help you speed up your requests as all ad loading will be prevented.
Note, that this parameter is unnecessary if JavaScript rendering has been disabled.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'block_ads': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:block_ads => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true');
To block resources (images & CSS) when scraping pass block_resources=true, this can also help you speed up your requests as all resource loading will be prevented.
Note, that this parameter is unnecessary if JavaScript rendering has been disabled.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'block_resources': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:block_resources => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true');
Most websites take some time to fully render their full content. Using the wait parameter you can tell GridPanel to wait before it returns the fully rendered HTML.
The wait parameter can be a value in milliseconds between 0 and 35000.
Below you can see an example where we are waiting 10000ms (10 seconds) for the page to load before we return the HTML.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'wait': '10000',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:wait => '10000',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000');
Instead of waiting a fixed amount of time, you might just want to wait for a particular element to appear in the DOM before returning the HTML.
You can utilise the wait_for parameter to pass a CSS/XPath selector to wait for before returning any HTML.
Below you can see an example of us waiting for the div element with a class value of a-loading-div, therefore we can use wait_for=.a-loading-div
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'wait_for': '.a-loading-div',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:wait_for => '.a-loading-div',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div');
Instead of waiting for a specific time period, or for an element to appear, you can wait until specific network conditions have been met.
This parameter can take one of 4 different values:
Below you can see an example where we are waiting for the DOM to load by passing wait_browser=domcontentloaded.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'wait_browser': 'domcontentloaded',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:wait_browser => 'domcontentloaded',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded');
If you need to extract any data from the pages you scrape, and don't want to process any HTML on your side, you can take advantage of our extraction rules.
These rules are passed through the extract_rules parameter and use the following syntax:
{ "key_name": "css_or_xpath_selector" }
For example, if you are looking to extract the title, and subtitle of a blog post you will need to use rules that look like the following:
{
"title": "h1",
"subtitle": "#subtitle"
}
This will then return the following JSON response:
{
"title": "Your blog title",
"subtitle": "Your blog subtitle"
}
It's important to note that these rules are JSON formatted and therefore need to be stringified when you pass them with your requests. You can see an example request here:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'extract_rules': '{"title": "h1", "subtitle": "#subtitle"}',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:extract_rules => '{"title": "h1", "subtitle": "#subtitle"}',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D');
To interact with pages you want to scrape before we return the HTML you can add a JavaScript scenario to your API calls.
For example, to click a button, you can use the following scenario:
{
"instructions": [
{ "click": "#buttonId"}
]
}
This will result with the following API call:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'js_scenario': '{"instructions": [{"click": "#buttonId"}]}',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:js_scenario => '{"instructions": [{"click": "#buttonId"}]}',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D');
Again please note that the JavaScript scenario parameter is JSON formatted, which means you need to stringify it when you pass it to your API requests.
Each scenario can have multiple instructions, and they will be executed in the order you send them before returning the HTML of the page.
The supported instructions are as follows:
{
"instructions": [
{"click": "#buttonId"}, // Click a button
{"wait": 1000}, // Wait a fixed duration in ms
{"wait_for": #a_div}, // Wait for a specific element
{"wait_for_and_click": #a_div}, // Wait for an element and click it
{"scroll_x": 1000}, // Scroll the screen in the horizontal axis, in px
{"scroll_y": 1000}, // Scroll the screen in the vertical axis, in px
{"fill": ["#input_1", "value_1"]}, // Fill in some input
{"evaluate": "console.log(123)", // Evaluate custom javascript code
{"infinite_scroll": // Scroll the page until end
{
"max_count": 0, // Max number to scroll, 0 is forever
"delay": 1000, // Delay between every scroll in ms
"end_click": { "selector": "#button_id" } // Click a button when the end of the page is reached
}
}
]
}
If an instruction you need is not supported, you can use the evaluate instruction to run any JavaScript code that you need.
If you want your response format to be in JSON and you want to intercept the responses of XHR/Ajax requests you can use the json_response parameter.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'json_response': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:json_response => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true');
You will receive a response that looks like the following:
{
# Headers sent by the server
"headers": {
"Date": "Fri, 16 Apr 2021 15:03:54 GMT",
...
"Access-Control-Allow-Credentials": "true"
},
# Credit cost of your request
"cost": 1,
# Initial status code of the server
"initial-status-code": 200,
# Resolved URL (following redirection)
"resolved-url": "https://httpbin.org/",
# Type of the response "html" or "json" or "b64_bytes" for file, image, pdf,...
"type": "html",
# Content of the answer. Content will be base 64 encoded if is a file, image, pdf,...
"body": "<html>... </body>"
# base 64 encoded screenshot of the page, if screenshot=true is used
"screenshot": "b0918...aef",
# Cookies sent back by the server
"cookies": [
{
"name": "cookie_name",
"value": "cookie_value",
"domain": "test.com",
...
},
...
],
# Results of the JS scenario "evaluate" instructions
"evaluate_results": [...]
# Content and source of iframes in the page
"iframes": [
{
"content": "<html>... </body>",
"src": "https://site.com/iframe"
},
...
],
# XHR / Ajax requests sent by the browser
"xhr": [
{
# URL
"url": "https://",
# status code of the server
"status_code": 200,
# Method of the request
"method": "POST",
# Headers of the XHR / Ajax request
"headers": {
"pragma": "no-cache",
...
},
# Response of the XHR / Ajax request
"body": "2d,x"
},
...
],
# js_scenario detailed report ( only useful if using render_js=True and js_scenario=...)
"js_scenario_report": {
"task_executed": 1,
"task_failure": 0,
"task_success": 1,
"tasks": [
{
"duration": 3.042,
"params": 3000,
"success": true,
"task": "wait"
}
],
"total_duration": 3.042
},
# Metada / Schema data
"metadata": {
"microdata": ...,
"json-ld": ...,
}
}
If you need the HTML returned by the server, unchanged by the browser (before any JavaScript has been executed), you can pass return_page_source=true
If you have disabled JavaScript rendering, this parameter will do nothing and is unnecessary.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'return_page_source': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:return_page_source => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true');
In some instances you need to re-use the same browser context and IP address across multiple requests. For example, if you need to preserve cookies across requests.
You can achieve this by creating a session which will last 30 seconds from the last request made, for a maximum of 20 minutes. To create a session, pass create_session=true to your API calls and it will return to you the html of the page as well as a session_id which you can then use in later requests.
Below you can see how we can create a session:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'create_session': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:create_session => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true');
This will return a session_id uuid like below:
{
...
"session_id": "717094a8-f324-451f-8cc3-81c6e3f1205d",
...
}
Read on to understand how to use the session_id parameter
Once you have obtained your session_id using create_session=true you can route your requests through the same browser context.
To do this, you need to pass the session_id to all your API calls as follows:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'session_id': '717094a8-f324-451f-8cc3-81c6e3f1205d',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:session_id => '717094a8-f324-451f-8cc3-81c6e3f1205d',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d');
Every request you make with the session_id parameter will extend the session for 30 seconds. Your session cannot be longer than 20 minutes total.
If you require a screenshot of the page that you want to scrape, you can use the screenshot parameter.
Your response will then contain a screenshot key where the value is the screenshot data in base64.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true" > ./screenshot.png
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'screenshot': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:screenshot => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true');
Instead of taking a screenshot of the whole page, you can screenshot a specific CSS/XPath selector.
To achieve this, pass screenshot_selector=CSS_selector where CSS_selector is the the selector you want to capture.
For the hardest to scrape websites using premium_proxy=true is not enough. You can take advantage of our stealth api pool to scrape the hardest websites.
To use this proxy pool, pass stealth_proxy=true to your API calls.
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'stealth_proxy': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:stealth_proxy => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true');
If you want to use our scraping infrastructure but provide your own proxy you can use the own_proxy parameter. You can then take advantage of all GridPanel's features with your own proxy.
The syntax for suppling proxy information is as follows: {protocol}{username}:{password}@{host}:{port}
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'own_proxy': 'https://johndoe:password@my_proxy.com:1234',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:own_proxy => 'https://johndoe:password@my_proxy.com:1234',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234');
As well as using premium proxies, you are also able to chose the proxy location using the country_code parameter.
For example to use proxies from the United Kingdom you need to set premium_proxy=true
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'country_code': 'de',
'premium_proxy': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:country_code => 'de',
:premium_proxy => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true');
Choose the device that will send the request.
We currently support two device types: desktop (default) and mobile.
Below you can see an example where we are setting the device to desktop:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'device': 'desktop',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:device => 'desktop',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop');
Here we are setting the device to mobile:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'device': 'mobile',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:device => 'mobile',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile');
If you need to change the dimensions of the browser's viewport, when scraping you can use the window_width and window_height parameters.
Below you can see an example of setting window_width
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'window_width': '1500',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:window_width => '1500',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500');
If you need to change the dimensions of the browser's viewport, when scraping you can use the window_width and window_height parameters.
Below you can see an example of setting window_height
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'window_height': '500',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:window_height => '500',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500');
GridPanel's default behaviour is to return a HTTP 500 if the scraped URL returns something other than a 20x or a 404.
To get the same status code as the requested URL use the transparent_status_code parameter.
You can see an example of this below:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true"
import requests
params = {
'api_key': 'API_KEY',
'url': 'YOUR-URL',
'transparent_status_code': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'YOUR-URL',
:transparent_status_code => 'true',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true');
In some circumstances you might need to forward certain headers to the website that you want to scrape.
To achieve this, you need to set forward_headers to true and then pass your custom headers.
To forward headers, you must ensure that you prefix each header with "Spb-" for "Scraping Browser". We will trim the prefix and send the headers to the target website.
Below you can see an example of how to forward the Accept-Language header to the target site:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true" -H "Spb-Accept-Language:En-US"
import requests
headers = {
'Spb-Accept-Language': 'En-US',
}
params = {
'api_key': 'API_KEY',
'url': 'http://httpbin.org/headers?json',
'forward_headers': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params, headers=headers)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'http://httpbin.org/headers?json',
:forward_headers => 'true',
}
uri.query = URI.encode_www_form(params)
req = Net::HTTP::Get.new(uri)
req['Spb-Accept-Language'] = 'En-US'
req_options = {
use_ssl: uri.scheme == 'https'
}
res = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(req)
end
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true", nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Spb-Accept-Language", "En-US")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Spb-Accept-Language: En-US',
]);
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true"))
.GET()
.setHeader("Spb-Accept-Language", "En-US")
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true', {
headers: {
'Spb-Accept-Language': 'En-US'
}
});
If you want to forward headers, but you want to ensure those are the only headers that get sent with your requests, you can use forward_headers_pure.
To achieve this, you need to set forward_headers_pure to true and then pass your custom headers.
To forward headers, you must ensure that you prefix each header with "Spb-" for "Scraping Browser". We will trim the prefix and send the headers to the target website.
Below you can see an example of how to forward the Accept-Language header to the target site:
curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true" -H "Spb-Accept-Language:En-US"
import requests
headers = {
'Spb-Accept-Language': 'En-US',
}
params = {
'api_key': 'API_KEY',
'url': 'http://httpbin.org/headers?json',
'forward_headers_pure': 'true',
}
response = requests.get('https://gridpanel.net/api/scrape', params=params, headers=headers)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape')
params = {
:api_key => 'API_KEY',
:url => 'http://httpbin.org/headers?json',
:forward_headers_pure => 'true',
}
uri.query = URI.encode_www_form(params)
req = Net::HTTP::Get.new(uri)
req['Spb-Accept-Language'] = 'En-US'
req_options = {
use_ssl: uri.scheme == 'https'
}
res = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(req)
end
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true", nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Spb-Accept-Language", "En-US")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Spb-Accept-Language: En-US',
]);
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true"))
.GET()
.setHeader("Spb-Accept-Language", "En-US")
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true', {
headers: {
'Spb-Accept-Language': 'En-US'
}
});
Allows you to programmatically monitor credit consumption and currency usage.
Results are available in real time, and will not increase your request concurrency and will not cost credits.
curl 'https://gridpanel.net/api/scrape/usage?api_key=API_KEY'
import requests
params = {
'api_key': 'API_KEY',
}
response = requests.get('https://gridpanel.net/api/scrape/usage', params=params)
require 'net/http'
uri = URI('https://gridpanel.net/api/scrape/usage')
params = {
:api_key => 'API_KEY',
}
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape/usage?api_key=API_KEY", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape/usage?api_key=API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($ch);
curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gridpanel.net/api/scrape/usage?api_key=API_KEY"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape/usage?api_key=API_KEY');
{
"result": {
"max_api_credit": 100000,
"used_api_credit": 301,
"max_concurrency": 5,
"used_concurrency": 1,
"renewal_date": "Free Trial"
}
Every GridPanel plan will provide you a certain number of API credits per month.
Each request costs a different amount of credits based on the parameters you pass with your API calls.
Below is a breakdown of these costs:
Feature used | Credit cost |
---|---|
Rotating Proxy without javascript rendering | 1 |
Rotating Proxy with javascript rendering (default) | 5 |
Premium Proxy without javascript rendering | 10 |
Premium Proxy with javascript rendering | 25 |
Stealth Proxy without javascript rendering | 75 |
Stealth Proxy with javascript rendering | 75 |
Creating a session | 50 |