Waiting for Things
Browserless offers 4 different ways to wait for preconditions to be met on page. These are events, functions, selectors and timeouts
waitForEvent
Waits for an event to happen on the page before cotinue
Example
- JSON payload
- cURL
- Javascript
- Python
- Java
- C#
// Will fail since the event never fires
{
"url": "https://example.com/",
"waitForEvent": {
"event": "fullscreenchange",
"timeout": 5000
}
}
curl -X POST \
https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN_HERE \
-H 'Cache-Control: no-cache' \
-H 'Content-Type': 'application/json' \
-d '{
"url": "https://example.com/",
"waitForEvent": {
"event": "fullscreenchange",
"timeout": 5000
}
}' \
--output "screenshot.png"
import fs from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/screenshot?token=${TOKEN}`;
const headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
};
const data = {
url: "https://example.com/",
waitForEvent: {
event: "fullscreenchange",
timeout: 5000
}
};
const takeScreenshot = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
const imageBuffer = await response.arrayBuffer();
await fs.writeFile("screenshot.png", Buffer.from(imageBuffer));
console.log("Screenshot saved as screenshot.png");
};
takeScreenshot();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/screenshot?token={TOKEN}"
headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
}
data = {
"url": "https://example.com/",
"waitForEvent": {
"event": "fullscreenchange",
"timeout": 5000
}
}
response = requests.post(url, headers=headers, json=data)
with open("screenshot.png", "wb") as file:
file.write(response.content)
print("Screenshot saved as screenshot.png")
import java.io.*;
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
public class TakeScreenshotWithWaitForEvent {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/screenshot?token=" + TOKEN;
String jsonData = """
{
"url": "https://example.com/",
"waitForEvent": {
"event": "fullscreenchange",
"timeout": 5000
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
Files.copy(response.body(), Paths.get("screenshot.png"), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Screenshot saved as screenshot.png");
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/screenshot?token={TOKEN}";
string jsonData = @"
{
""url"": ""https://example.com/"",
""waitForEvent"": {
""event"": ""fullscreenchange"",
""timeout"": 5000
}
}";
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(jsonData, Encoding.UTF8, "application/json")
};
request.Headers.Add("Cache-Control", "no-cache");
try
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var imageBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("screenshot.png", imageBytes);
Console.WriteLine("Screenshot saved as screenshot.png");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
waitForFunction
Waits for the provided function to return before cotinue. The function can be any valid JavaScript or EcmaScript function, and async
functions are supported.
Example
JS function
async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const json = await res.json();
document.querySelector("h1").innerText = json.title;
};
- JSON payload
- cURL
- Javascript
- Python
- Java
- C#
{
"url": "https://example.com/",
"waitForFunction": {
"fn": "async()=>{let t=await fetch('https://jsonplaceholder.typicode.com/todos/1'),e=await t.json();document.querySelector('h1').innerText=e.title}",
"timeout": 5000
}
}
curl -X POST \
https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN_HERE \
-H 'Cache-Control: no-cache' \
-H 'Content-Type': 'application/json' \
-d '{
"url": "https://example.com/",
"waitForFunction": {
"fn": "async()=>{let t=await fetch('https://jsonplaceholder.typicode.com/todos/1'),e=await t.json();document.querySelector('h1').innerText=e.title}",
"timeout": 5000
}
}' \
--output "screenshot.png"
import fs from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/screenshot?token=${TOKEN}`;
const headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
};
const data = {
url: "https://example.com/",
waitForFunction: {
fn: "async()=>{let t=await fetch('https://jsonplaceholder.typicode.com/todos/1'),e=await t.json();document.querySelector('h1').innerText=e.title}",
timeout: 5000
}
};
const takeScreenshot = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
const imageBuffer = await response.arrayBuffer();
await fs.writeFile("screenshot.png", Buffer.from(imageBuffer));
console.log("Screenshot saved as screenshot.png");
};
takeScreenshot();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/screenshot?token={TOKEN}"
headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
}
data = {
"url": "https://example.com/",
"waitForFunction": {
"fn": "async()=>{let t=await fetch('https://jsonplaceholder.typicode.com/todos/1'),e=await t.json();document.querySelector('h1').innerText=e.title}",
"timeout": 5000
}
}
response = requests.post(url, headers=headers, json=data)
with open("screenshot.png", "wb") as file:
file.write(response.content)
print("Screenshot saved as screenshot.png")
import java.io.*;
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
public class TakeScreenshotWithWaitForFunction {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/screenshot?token=" + TOKEN;
String jsonData = """
{
"url": "https://example.com/",
"waitForFunction": {
"fn": "async()=>{let t=await fetch('https://jsonplaceholder.typicode.com/todos/1'),e=await t.json();document.querySelector('h1').innerText=e.title}",
"timeout": 5000
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
Files.copy(response.body(), Paths.get("screenshot.png"), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Screenshot saved as screenshot.png");
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/screenshot?token={TOKEN}";
string jsonData = @"
{
""url"": ""https://example.com/"",
""waitForFunction"": {
""fn"": ""async()=>{let t=await fetch('https://jsonplaceholder.typicode.com/todos/1'),e=await t.json();document.querySelector('h1').innerText=e.title}"",
""timeout"": 5000
}
}";
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(jsonData, Encoding.UTF8, "application/json")
};
request.Headers.Add("Cache-Control", "no-cache");
try
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var imageBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("screenshot.png", imageBytes);
Console.WriteLine("Screenshot saved as screenshot.png");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
waitForSelector
Wait for a selector to appear in page. If at the moment of calling the method the selector already exists, the method will return immediately. If the selector doesn't appear after the timeout milliseconds of waiting, the function will throw.
The object can have any of these values:
selector
: String, required — A valid CSS selector.hidden
Boolean, optional — Wait for the selected element to not be found in the DOM or to be hidden, i.e. havedisplay: none
orvisibility: hidden
CSS properties.timeout
: Number, optional — Maximum number of milliseconds to wait for the selector before failing.visible
: Boolean, optional — Wait for the selected element to be present in DOM and to be visible, i.e. to not havedisplay: none
orvisibility: hidden
CSS properties.
Example
Rest API (Without Stealth)
- JSON payload
- cURL
- Javascript
- Python
- Java
- C#
{
"url": "https://example.com/",
"waitForSelector": {
"selector": "h1",
"timeout": 5000
}
}
curl -X POST \
https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN_HERE \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"waitForSelector": {
"selector": "h1",
"timeout": 5000
}
}'
import fs from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/screenshot?token=${TOKEN}`;
const headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
};
const data = {
url: "https://example.com/",
waitForSelector: {
selector: "h1",
timeout: 5000
}
};
const generatePDF = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
const pdfBuffer = await response.arrayBuffer();
await fs.writeFile("output.pdf", Buffer.from(pdfBuffer));
console.log("PDF saved as output.pdf");
};
generatePDF();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/screenshot?token={TOKEN}"
headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
}
data = {
"url": "https://example.com/",
"waitForSelector": {
"selector": "h1",
"timeout": 5000
}
}
response = requests.post(url, headers=headers, json=data)
with open("output.pdf", "wb") as file:
file.write(response.content)
print("PDF saved as output.pdf")
import java.io.*;
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
public class GeneratePDFWithWaitForSelector {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/screenshot?token=" + TOKEN;
String jsonData = """
{
"url": "https://example.com/",
"waitForSelector": {
"selector": "h1",
"timeout": 5000
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
Files.copy(response.body(), Paths.get("output.pdf"), StandardCopyOption.REPLACE_EXISTING);
System.out.println("PDF saved as output.pdf");
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/screenshot?token={TOKEN}";
string jsonData = @"
{
""url"": ""https://example.com/"",
""waitForSelector"": {
""selector"": ""h1"",
""timeout"": 5000
}
}";
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(jsonData, Encoding.UTF8, "application/json")
};
request.Headers.Add("Cache-Control", "no-cache");
try
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("output.pdf", pdfBytes);
Console.WriteLine("PDF saved as output.pdf");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
BQL (Stealth)
If the /pdf API
is getting blocked by bot detectors, then we would recommend trying BrowserQL.
- BQL Query
- cURL
- Javascript
- Python
- Java
- C#
mutation PDF {
goto(url: "https://example.com/") {
status
}
waitForSelector(selector: "h1" timeout: 5000) {
selector
}
}
curl --request POST \
--url 'https://production-sfo.browserless.io/chromium/bql?token=YOUR_API_TOKEN_HERE' \
--header 'Content-Type: application/json' \
--data '{"query":"mutation PDF {\n goto(url: \"https://example.com/\") {\n status\n }\n\n waitForSelector(selector: \"h1\" timeout: 5000) {\n selector\n }\n}","variables":"","operationName":"PDF"}'
const endpoint = "https://production-sfo.browserless.io/chromium/bql";
const token = "YOUR_API_TOKEN_HERE";
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({"query":"mutation PDF {\n goto(url: \"https://example.com/\") {\n status\n }\n\n waitForSelector(selector: \"h1\" timeout: 5000) {\n selector\n }\n}","variables":"","operationName":"PDF"})
};
const url = `${endpoint}?token=${token}`;
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
import requests
endpoint = "https://production-sfo.browserless.io/chromium/bql"
query_string = {
"token": "YOUR_API_TOKEN_HERE",
}
headers = {
"Content-Type": "application/json",
}
payload = {
"query": "mutation PDF {\n goto(url: \"https://example.com/\") {\n status\n }\n\n waitForSelector(selector: \"h1\" timeout: 5000) {\n selector\n }\n}",
"variables": None,
"operationName": "PDF",
}
response = requests.post(endpoint, params=query_string, headers=headers, json=payload)
print(response.json())
String url = "https://production-sfo.browserless.io/chromium/bql";
String token = "YOUR_API_TOKEN_HERE";
String endpoint = String.format("%s?token=%s%s%s", url, token);
HttpResponse<String> response = Unirest.post(endpoint)
.header("Content-Type", "application/json")
.body({"query":"mutation PDF {\n goto(url: \"https://example.com/\") {\n status\n }\n\n waitForSelector(selector: \"h1\" timeout: 5000) {\n selector\n }\n}","variables":"","operationName":"PDF"})
.asString();
string url = "https://production-sfo.browserless.io/chromium/bql";
string token = "YOUR_API_TOKEN_HERE";
string endpoint = $"{url}?token={token}";
var payload = new
{
query = @"mutation PDF {
goto(url: ""https://example.com/"") {
status
}
waitForSelector(selector: ""h1"" timeout: 5000) {
selector
}
}",
variables = "",
operationName = "PDF"
};
using (var client = new HttpClient())
{
var jsonPayload = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(endpoint, content);
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
For more details on BQL mutations, refer to the BrowserQL Schema reference pages.