Skip to content

Puppeteer

Puppeteer attaches with puppeteer.connect({ browserWSEndpoint }). The endpoint is what /connect returns.

Install puppeteer-core, not puppeteer. The full package downloads a Chromium you will never launch.

// npm install puppeteer-core
// Save as puppeteer.mjs and run: node puppeteer.mjs
import puppeteer from 'puppeteer-core';
const API = 'https://browser.rayobyte.com';
const KEY = process.env.RAYOBYTE_KEY;
const PROXY = 'http://USERNAME:[email protected]:8000';
async function createBrowser() {
const url = new URL('/connect', API);
url.searchParams.set('os', 'windows');
url.searchParams.set('proxy', PROXY);
const resp = await fetch(url, { headers: { 'x-api-key': KEY } });
if (!resp.ok) throw new Error(`${resp.status}: ${await resp.text()}`);
return {
cdpUrl: (await resp.text()).trim(),
sessionId: resp.headers.get('x-session-id'),
};
}
async function closeBrowser(sessionId) {
await fetch(`${API}/api/browser/close`, {
method: 'POST',
headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
body: JSON.stringify({ browserId: sessionId }),
});
}
const { cdpUrl, sessionId } = await createBrowser();
console.log(`Session: ${sessionId}`);
try {
const browser = await puppeteer.connect({ browserWSEndpoint: cdpUrl });
const page = (await browser.pages())[0] ?? (await browser.newPage());
await page.goto('https://quotes.toscrape.com/', { waitUntil: 'domcontentloaded' });
console.log(await page.title()); // Quotes to Scrape
await browser.disconnect();
} finally {
await closeBrowser(sessionId);
}

Run it with the key in the environment: RAYOBYTE_KEY=rb_live_YOUR_KEY node puppeteer.mjs.

browser.disconnect() detaches Puppeteer and the browser keeps running. browser.close() shuts Chromium down, and the session ends as DEAD rather than CLOSED. Either way, POST /api/browser/close with the x-session-id value is the call that ends a session cleanly, and it is the only way to end one you disconnected from.

To keep a browser between runs, skip closeBrowser(), store sessionId, and reconnect later with GET /connect?sessionId=.... A disconnected browser you never close runs for the rest of its maxLifetime, which is 7,200 seconds by default, and bills every second of it.

page.setUserAgent() replaces the string the fingerprint set, leaving it at odds with the client hints and navigator.platform. Same for page.setExtraHTTPHeaders({'User-Agent': ...}). Leave both alone.

Was this page helpful?