# Add task instructions Source: https://docs.browser.ai/api-reference/endpoint/addInstructions POST /tasks/{session_id}/instructions Add (append) instructions to an existing task. For example: provide an OTP code after initiating a login task. # Create saved task Source: https://docs.browser.ai/api-reference/endpoint/createSavedTask POST /saved_tasks Create a reusable saved task using natural language instructions. This is useful for automating recurring workflows with predefined settings. # Force stop a task Source: https://docs.browser.ai/api-reference/endpoint/forceStop POST /tasks/{session_id}/command Use this endpoint to stop to an active task session. # Get list of saved tasks Source: https://docs.browser.ai/api-reference/endpoint/getSavedTaskList GET /saved_tasks Returns a list of all saved tasks associated with the authenticated user. Each task includes its name, project, location, and instruction details. # Get saved task by name Source: https://docs.browser.ai/api-reference/endpoint/getSavedTaskName GET /saved_tasks/name/{task_name} Retrieve a specific saved task by its name. This is helpful for accessing or reusing previously saved automation tasks. # Get task results Source: https://docs.browser.ai/api-reference/endpoint/results GET /results/{session_id} Fetch the final results of a completed task, including output, metadata, and console logs. Use the session ID to identify the task. # Get task metadata Source: https://docs.browser.ai/api-reference/endpoint/taskMetadata GET /tasks/{session_id} Retrieve metadata and status information for a specific task using its session ID. This includes execution status, timestamps, and progress logs. # Create a new task Source: https://docs.browser.ai/api-reference/endpoint/tasks POST /tasks This endpoint allows you to create a new task using either natural language (crawler_automation) or code instructions (script_automation). You must specify the execution engine, project, location, and task steps. # Update task instructions Source: https://docs.browser.ai/api-reference/endpoint/updateInstructions PUT /tasks/{session_id}/instructions Update (replace) instructions for an existing task, use this to overwrite the full set of task instructions. # BrowserAI API Source: https://docs.browser.ai/api-reference/intro The **BrowserAI** API enables developers to programmatically create, manage, and retrieve results from browser-based automation tasks powered by AI. This API is designed to help you automate web interactions, extract data, scrape, and run scripts in our cloud-based browser environment with customizable geographic targeting. Whether you're building a data extraction pipeline, automating web testing, or integrating browser automation into your product, this API provides a secure and scalable interface to manage your automation workflows. ## Getting Started 1. [Obtain your API key](https://docs.browser.ai/api-reference/token) from the Projects Dashboard. 2. Create a **task** by sending a request to /tasks with your prompt and geo settings. 3. **Track** the task using the `session ID` returned. 4. **Fetch results** once the task is completed! ## Authentication All endpoints are secured using an API key. You must include your API key in the Authorization header using the following format: ```javascript theme={null} Authorization: apikey ``` ## Available Endpoints | **Method** | **Endpoint** | **Description** | | ---------------------------------------------------------------------- | ------------------------------- | -------------------------------------------- | | [POST](https://docs.browser.ai/api-reference/endpoint/tasks) | `/tasks` | Create a new task. | | [POST](https://docs.browser.ai/api-reference/endpoint/forceStop) | `/tasks/{session_id}/command` | Force stop a task. | | [GET](https://docs.browser.ai/api-reference/endpoint/taskMetadata) | `/tasks/{session_id}` | Get metadata, progress and status of a task. | | [GET](https://docs.browser.ai/api-reference/endpoint/results) | `/results/{session_id}` | Retrieve the results of a task. | | [POST](https://docs.browser.ai/api-reference/endpoint/createSavedTask) | `/saved_tasks` | Create a saved task. | | [GET](https://docs.browser.ai/api-reference/endpoint/getSavedTaskList) | `/saved_tasks` | Get list of saved tasks. | | [GET](https://docs.browser.ai/api-reference/endpoint/getSavedTaskName) | `/saved_tasks/name/{task_name}` | Get a saved task by name. | # BrowserAI n8n node Source: https://docs.browser.ai/api-reference/n8n-node The BrowserAI n8n node allows you to seamlessly integrate BrowserAI’s powerful browser automation and capabilities into your n8n workflows — in seconds! title ## What is n8n? **n8n** is a powerful, open-source workflow automation tool that lets you connect apps, APIs, and services with a visual, no-code interface. It enables you to build complex automations using over 300 integrations or custom logic with JavaScript. ## Why use BrowserAI with n8n? **n8n-nodes-browserai** is a custom community node built by us for n8n, allowing you to perform everything you can do on the BrowserAI dashboard — directly within your n8n workflows! From creating and managing tasks to automating workflows, commercial and data monitoring, and integrating BrowserAI with other services, this node brings the full power of BrowserAI into your automation stack. ## How to integrate BrowserAI with n8n? Head to BrowserAI's [npm page](https://www.npmjs.com/package/n8n-nodes-browserai) to download the node, or simpley run this in curl: ```bash theme={null} npm i n8n-nodes-browserai ``` ## How to use BrowserAI with n8n? Example for a simple task followed by viewing its metadata and results. Click the **+ button** in the top-right corner of your workspace to add a new node. Search for **BrowserAI** in the node list and select it. Click **Create new credentials** to connect your BrowserAI account. Paste your **API Key** from the BrowserAI dashboard and click **Save**. Don't know where to find your API key? find out [here](https://docs.browser.ai/api-reference/token). Set the operation to 'Create Task', select your Project, choose a Country, and set Task Type to 'Crawler Type' for natural-language tasks. Then, **execute the node!** Once executed, the task will appear immediately in your BrowserAI [dashboard](https://browser.ai/dashboard/page/overview). Now lets give it another try and this time **fetch the task Metadata** by choosing 'Get task metadata' as our Operation, enter the 'Task Session ID', and execute the node to view metadata and **results** on the right panel. 📧 [Contact us](mailto:support@browser.ai) — we’re happy to help you get started or brainstorm use cases! # BrowserAI API key Source: https://docs.browser.ai/api-reference/token Can't locate your API key? No worries — here's how to track it down like a pro. You can find your **API key** by navigating to Dashboard → Account → API Key, or simply click [here](https://browser.ai/dashboard/page/account/tab/api_key). You’ll see your key right away. Need a new one? Hit **Refresh Token**, just remember the old key will no longer work! # Change Location Source: https://docs.browser.ai/api-token/api-geolocation The **geoLocation** parameter allows you to flexibly modify your proxy’s geographic position within a defined country. It’s ideal for collecting region-specific data, testing localized content, and mimicking user activity from different parts of the world. This helps ensure precise data extraction, accurate regional testing, and access to geo-restricted websites. To change the location in the **API Token tab**, simply update the 2-letter country code within the `{"country":"XX"}` field of the **cURL request** to your desired country. # BrowserAI task API Source: https://docs.browser.ai/api-token/api-intro The **BrowserAI** API offers developers a powerful interface to launch, control, and collect output from AI-driven browser automation tasks. Built for flexibility, it allows you to automate web actions, gather content, perform scraping, and execute scripts within a cloud-hosted browser—complete with customizable location targeting. Ideal for **building data pipelines, automating testing processes, or embedding browser automation into your own applications**, this API delivers a robust, secure, and scalable solution for managing complex web-based workflows with ease. ### API Workflow 1. Start by retrieving your **API key** from the Project Dashboard. 1. Create a task by either running the provided **cURL command in CMD** or sending a request to the `/tasks` endpoint with your **prompt and location settings**. 1. If you used the **API endpoint**, you can track the task using the returned `session ID`. 2. You can fetch task **metadata** by calling `/tasks/{session_id}` method and view the response structure similar to this: ``` { "executionId": "", "scriptId": "", "scriptType": "", "status": "", "progress": { "status": "", "logs": [ "" ] }, "started": "2023-11-07T05:31:56Z", "estimatedCompletion": "2023-11-07T05:31:56Z" } ``` 1. Once completed, retrieve the **final results** by sending a request to the `/results/{session_id}` method and recieve this output: ``` { "executionId": "", "status": "", "started": "2023-11-07T05:31:56Z", "completed": "2023-11-07T05:31:56Z", "results": [ { "model_output": "", "result": "", "state": "", "metadata": {}, "history_index": 123, "screenshot_url": "", "html_url": "", "console_url": "", "insert_ts": "2023-11-07T05:31:56Z" } ] } ``` Explore more in-depth information about our API [here](https://docs.browser.ai/api-reference/intro)! # Crawler Automation Source: https://docs.browser.ai/api-token/crawler-automation Crawler Automation Use is an easy way to connect your AI agents with the browser to make is accessible! **Crawler Automation** is the easiest way to connect your AI agents with the browser, offering a powerful yet simple interface for browser automation that makes websites easily accessible for AI-driven tasks. Whether it's writing in Google Docs, filling out job applications, collecting data, or searching for flights, Crawler Automation enables seamless interaction with web content. ## How to use it: ### Via API Documentation: To leverage this capability in your **BrowserAI** tasks, simply set the `type` parameter to `Crawler Automation` in the [API Reference](https://docs.browser.ai/api-reference/endpoint/tasks) when creating a new task and write an instruction in plain human language — no complex coding required. ### Via Dashboard: Use **BrowserAI** together with **Crawler Automation** as explained in the Task API. In addition, to visualize the actions of BrowserAI head to [Playground tab](https://browser.ai/dashboard/page/live/tab/page/live). There you'll be able to choose **Natural Language**, country and add prompts for BrowserAI to perform. Then you can watch how the actions are being done on your right window in live! Once you go to [Playground tab](https://browser.ai/dashboard/page/live/tab/page/live), ensure it's set to **Natual language**. Choose a country, give it prompts to perform and hit the **Run** button. Watch the live session unfold on the right-hand screen as BrowserAI carries out your task! When the task is complete, you'll receive a summary window with a playback video and ready-to-use cURL commands to view the task's metadata and results. # Script Automation Source: https://docs.browser.ai/api-token/script-automation Script Automation allows you to automate browsers with natural language and code! **Script Automation** lets you do anything a web browser can do, offering a powerful framework for building browser automations that are repeatable, customizable, and maintainable. By combining AI agents, AI tools, and standard Playwright functionality, Script Automation gives you full control over the complexity and behavior of your automations—whether simple or highly advanced. To use Script Automation in your **BrowserAI** tasks, just set the `type` parameter to `Script Automation` and provide your instructions using a mix of human language inside TypeScript functions. With intuitive methods like `page.act()` for executing natural language actions, `page.extract()` for pulling structured data from pages, and `page.observe()` for previewing actions before execution, Script Automation makes it easy to build intelligent, flexible browser workflows. ### Examples: Extract the title of medium.com ``` await page.goto('https://medium.com/'); await page.extract({ instruction: 'extract the title of the page', schema: z.object({title: z.string()}), }); ``` Extract three prices of AirPods Pro 2 from Amazon ``` await page.goto('https://www.amazon.com/'); await page.act('search for AirPods Pro 2'); await page.extract({ instruction: 'extract the three best prices available', schema: z.object({ prices: z.array(z.number()), }), }); ``` Extract the latest article from browser.ai ``` await page.goto('https://browser.ai/news/'); await page.act('open the most recent article'); await page.extract({ instruction: 'extract the article title and summary paragraph', schema: z.object({ title: z.string(), summary: z.string(), }), }); ``` # BrowserAI Code Snippets Source: https://docs.browser.ai/general/code-snippets Explore real-world code examples to integrate BrowserAI with Playwright, Puppeteer, and Selenium. Ensure you have the required libraries installed before proceeding. ## Basic Web Scraping **Select Your Tech Stack:** ```js Playwright theme={null} const playwright = require('playwright'); const AUTH = process.env.AUTH || 'USER:PASS'; const TARGET_URL = process.env.TARGET_URL || 'https://example.com'; async function scrape(url = TARGET_URL) { if (AUTH === 'USER:PASS') { throw new Error('🔑 Missing credentials! Update the AUTH environment variable.'); } console.log(`🚀 Connecting to browser.ai...`); const endpointURL = `wss://${AUTH}@brd.superproxy.io:9222`; const browser = await playwright.chromium.connectOverCDP(endpointURL); try { console.log(`🌎 Navigating to ${url}...`); const page = await browser.newPage(); await page.goto(url, { timeout: 120000 }); console.log(`📄 Extracting page content...`); const data = await page.content(); console.log(`✅ Data scraped:`, data); } finally { await browser.close(); } } scrape().catch(err => console.error(`❌ Error:`, err)); ``` ```js Puppeteer theme={null} const puppeteer = require('puppeteer-core'); const AUTH = process.env.AUTH || 'USER:PASS'; const TARGET_URL = process.env.TARGET_URL || 'https://example.com'; async function scrape(url = TARGET_URL) { if (AUTH === 'USER:PASS') { throw new Error('🔑 Missing credentials! Update the AUTH environment variable.'); } console.log(`🚀 Connecting to browser.ai...`); const browserWSEndpoint = `wss://${AUTH}@brd.superproxy.io:9222`; const browser = await puppeteer.connect({ browserWSEndpoint }); try { console.log(`🌎 Navigating to ${url}...`); const page = await browser.newPage(); await page.goto(url, { timeout: 120000 }); console.log(`📄 Extracting page content...`); const data = await page.content(); console.log(`✅ Data scraped:`, data); } finally { await browser.close(); } } scrape().catch(err => console.error(`❌ Error:`, err)); ``` ```python Playwright theme={null} from playwright.sync_api import sync_playwright import os AUTH = os.getenv("AUTH", "USER:PASS") TARGET_URL = os.getenv("TARGET_URL", "https://example.com") def scrape(url=TARGET_URL): if AUTH == "USER:PASS": raise ValueError("🔑 Missing credentials! Update the AUTH environment variable.") print("🚀 Connecting to browser.ai...") endpoint_url = f"wss://{AUTH}@brd.superproxy.io:9222" with sync_playwright() as p: browser = p.chromium.connect_over_cdp(endpoint_url) try: print(f"🌎 Navigating to {url}...") page = browser.new_page() page.goto(url, timeout=120000) print("📄 Extracting page content...") data = page.content() print(f"✅ Data scraped: {data}") finally: browser.close() scrape() ``` ```cs PuppeteerSharp theme={null} using PuppeteerSharp; using System; class Program { private static string AUTH = Environment.GetEnvironmentVariable("AUTH") ?? "USER:PASS"; private static string TARGET_URL = Environment.GetEnvironmentVariable("TARGET_URL") ?? "https://example.com"; static async Task Main() { if (AUTH == "USER:PASS") { throw new Exception("🔑 Missing credentials! Update the AUTH environment variable."); } Console.WriteLine("🚀 Connecting to browser.ai..."); var browser = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = $"wss://{AUTH}@brd.superproxy.io:9222" }); try { Console.WriteLine($"🌎 Navigating to {TARGET_URL}..."); var page = await browser.NewPageAsync(); await page.GoToAsync(TARGET_URL, new NavigationOptions { Timeout = 120000 }); Console.WriteLine("📄 Extracting page content..."); var data = await page.GetContentAsync(); Console.WriteLine($"✅ Data scraped: {data}"); } finally { await browser.CloseAsync(); } } } ``` *** ## Debugging & Inspecting Your Session Want to **see** what's happening inside your browser.ai session? Open DevTools automatically: ```js Puppeteer theme={null} const { exec } = require('child_process'); const AUTH = process.env.AUTH || 'USER:PASS'; const browserWSEndpoint = `wss://${AUTH}@brd.superproxy.io:9222`; (async () => { console.log("🚀 Connecting to browser.ai..."); const browser = await puppeteer.connect({ browserWSEndpoint }); const page = await browser.newPage(); const client = await page.target().createCDPSession(); const { url: inspectUrl } = await client.send('Page.inspect'); console.log(`🛠 Open DevTools: ${inspectUrl}`); exec(`google-chrome "${inspectUrl}"`); })(); ``` ```python Playwright theme={null} from playwright.sync_api import sync_playwright import os, subprocess AUTH = os.getenv("AUTH", "USER:PASS") TARGET_URL = os.getenv("TARGET_URL", "https://example.com") def open_devtools(): if AUTH == "USER:PASS": raise ValueError("🔑 Missing credentials! Update the AUTH environment variable.") print("🚀 Connecting to browser.ai...") endpoint_url = f"wss://{AUTH}@brd.superproxy.io:9222" with sync_playwright() as p: browser = p.chromium.connect_over_cdp(endpoint_url) page = browser.new_page() client = page.context.new_cdp_session(page) inspect_url = client.send("Page.inspect")["url"] print(f"🛠 Open DevTools: {inspect_url}") subprocess.run(["google-chrome", inspect_url]) open_devtools() ``` ## Handling CAPTCHAs browser.ai can **automatically detect and solve CAPTCHAs** in real time: ```js Puppeteer theme={null} const puppeteer = require('puppeteer-core'); const AUTH = process.env.AUTH || 'USER:PASS'; const TARGET_URL = process.env.TARGET_URL || 'https://example.com'; (async () => { const browser = await puppeteer.connect({ browserWSEndpoint: `wss://${AUTH}@brd.superproxy.io:9222` }); const page = await browser.newPage(); await page.goto(TARGET_URL, { timeout: 120000 }); console.log("🔎 Checking for CAPTCHA..."); const client = await page.target().createCDPSession(); const { status } = await client.send("Captcha.solve", { detectTimeout: 30000 }); console.log(`🛠 CAPTCHA status: ${status}`); })(); ``` **BrowserAI makes web scraping easy, scalable, and unblockable.** Get started today! # Configuring BrowserAI Source: https://docs.browser.ai/general/configuration Set up BrowserAI for web automation. Get your credentials, run sample scripts, and inspect live sessions effortlessly. ## Setting Up BrowserAI Before diving into automation, let's **grab your credentials**. You’ll need your **API Token**, which you can find inside of your BrowserAI project. Make sure you have **Puppeteer, Playwright, or Selenium installed** before proceeding. ## Test Your Setup Run the sample code below to confirm that **BrowserAI is connected and working**. **Remember:** Replace `USER:PASS` with your actual credentials. ```js Puppeteer theme={null} const puppeteer = require('puppeteer-core'); // Enter your zone name and password below const AUTH = 'USER:PASS'; const SBR_WS_ENDPOINT = `wss://${AUTH}@brd.superproxy.io:9222`; async function main() { console.log('Connecting to BrowserAI...'); const browser = await puppeteer.connect({ browserWSEndpoint: SBR_WS_ENDPOINT, }); try { console.log('Connected! Navigating...'); const page = await browser.newPage(); // Enter your test URL below await page.goto('https://example.com', { timeout: 2 * 60 * 1000 }); console.log('Taking screenshot to page.png'); await page.screenshot({ path: './page.png', fullPage: true }); console.log('Navigated! browser.ai...'); const html = await page.content(); console.log(html) } finally { await browser.close(); } } if (require.main === module) { main().catch(err => { console.error(err.stack || err); process.exit(1); }); } ``` ```js Playwright theme={null} const puppeteer = require('puppeteer-core'); // Enter your zone name and password below const AUTH = 'USER:PASS'; const BBAI_WS_ENDPOINT = `wss://${AUTH}@brd.superproxy.io:9222`; async function main() { console.log('Connecting to browser.ai...'); const browser = await puppeteer.connect({ browserWSEndpoint: SBR_WS_ENDPOINT, }); try { console.log('Connected! Navigating...'); const page = await browser.newPage(); // Enter your test URL below await page.goto('https://example.com', { timeout: 2 * 60 * 1000 }); console.log('Taking screenshot to page.png'); await page.screenshot({ path: './page.png', fullPage: true }); console.log('Navigated! browser.ai content...'); const html = await page.content(); console.log(html) } finally { await browser.close(); } } if (require.main === module) { main().catch(err => { console.error(err.stack || err); process.exit(1); }); } ``` ```js Selenium theme={null} const { Builder, Browser } = require('selenium-webdriver'); const fs = require('fs/promises'); const AUTH = 'USER:PASS'; const BBAI_WEBDRIVER = `https://${AUTH}@brd.superproxy.io:9515`; (async () => { console.log('Connecting to browser.ai...'); const driver = await new Builder().forBrowser(Browser.CHROME).usingServer(BBAI_WEBDRIVER).build(); try { console.log('Navigating...'); await driver.get('https://example.com'); console.log('Taking screenshot...'); const screenshot = await driver.takeScreenshot(); await fs.writeFile('./page.png', Buffer.from(screenshot, 'base64')); console.log('Extracting page content...'); const html = await driver.getPageSource(); console.log(html); } finally { driver.quit(); } } if (require.main == module) { main().catch(err => { console.error(err.stack || err); process.exit(1); }); } ``` ```python Playwright theme={null} import asyncio from playwright.async_api import async_playwright AUTH = 'USER:PASS' BBAI_WS_CDP = f'wss://{AUTH}@brd.superproxy.io:9222' async def run(playwright): print("Connecting to browser.ai...") browser = await playwright.chromium.connect_over_cdp(BBAI_WS_CDP) try: print("Connected! Navigating...") page = await browser.new_page() await page.goto('https://example.com', timeout=120000) print("Taking screenshot...") await page.screenshot(path='./page.png', full_page=True) print("Extracting page content...") html = await page.content() print(html) finally: await browser.close() async def main(): async with async_playwright() as playwright: await run(playwright) if __name__ == '__main__': asyncio.run(main()) ``` ```python Selenium theme={null} from selenium.webdriver import Remote, ChromeOptions from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection AUTH = 'USER:PASS' BBAI_WEBDRIVER = f'https://{AUTH}@brd.superproxy.io:9515' def main(): print("Connecting to browser.ai...") sbr_connection = ChromiumRemoteConnection(BBAI_WEBDRIVER, 'goog', 'chrome') with Remote(sbr_connection, options=ChromeOptions()) as driver: print("Connected! Navigating...") driver.get('https://example.com') print("Taking screenshot...") driver.get_screenshot_as_file('./page.png') print("Extracting page content...") html = driver.page_source print(html) if __name__ == '__main__': main() ``` ```cs PuppeteerSharp theme={null} using PuppeteerSharp; using System.Net.WebSockets; using System.Text; var AUTH = "USER:PASS"; var BBAI_WS_ENDPOINT = $"wss://{AUTH}@brd.superproxy.io:9222"; var browser = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = BBAI_WS_ENDPOINT, WebSocketFactory = async (uri, _, cToken) => { var socket = new ClientWebSocket(); var authBytes = Encoding.UTF8.GetBytes(new Uri(BBAI_WS_ENDPOINT).UserInfo); var authHeader = "Basic " + Convert.ToBase64String(authBytes); socket.Options.SetRequestHeader("Authorization", authHeader); socket.Options.KeepAliveInterval = TimeSpan.Zero; await socket.ConnectAsync(uri, cToken); return socket; } }); Console.WriteLine("Connecting to browser.ai..."); using var browser = await Connect(SBR_WS_ENDPOINT); Console.WriteLine("Connected! Navigating..."); var page = await browser.NewPageAsync(); await page.GoToAsync("https://example.com", new NavigationOptions() { Timeout = 2 * 60 * 1000, }); Console.WriteLine("Taking page screenshot to file page.png"); await page.ScreenshotAsync("./page.png", new () { FullPage = true, }); Console.WriteLine("Navigated! Scraping page content..."); var html = await page.GetContentAsync(); Console.WriteLine(html); ``` ```cs Playwright theme={null} var AUTH = "USER:PASS"; var SBR_CDP = $"wss://{AUTH}@brd.superproxy.io:9222"; Console.WriteLine("Connecting to browser.ai..."); using var pw = await Playwright.CreateAsync(); await using var browser = await pw.Chromium.ConnectOverCDPAsync(SBR_CDP); Console.WriteLine("Connected! Navigating..."); var page = await browser.NewPageAsync(); await page.GotoAsync("https://example.com", new() { Timeout = 2 * 60 * 1000, }); Console.WriteLine("Taking page screenshot to file page.png"); await page.ScreenshotAsync(new () { Path = "./page.png", FullPage = true, }); Console.WriteLine("Navigated! browser.ai content..."); var html = await page.ContentAsync(); Console.WriteLine(html); ``` ```cs Selenium theme={null} using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Remote; var AUTH = "USER:PASS"; var SBR_WEBDRIVER = "https://{AUTH}@brd.superproxy.io:9515"; Console.WriteLine("Connecting to browser.ai..."); var options = new ChromeOptions(); using var driver = new RemoteWebDriver(new Uri(SBR_WEBDRIVER), options); Console.WriteLine("Connected! Navigating to https://example.com..."); driver.Navigate().GoToUrl("https://example.com"); Console.WriteLine("Taking page screenshot to file page.png"); var screenshot = driver.GetScreenshot(); screenshot.SaveAsFile("./page.png"); Console.WriteLine("Navigated! browser.ai content..."); var html = driver.PageSource; Console.WriteLine(html); ``` ## Live Debugging with DevTools Want a **real-time view** of your BrowserAI session? Run the snippet below to **auto-launch Chrome DevTools** every time you start a session. ```js Puppeteer theme={null} const { exec } = require('child_process'); const chromeExecutable = 'google-chrome'; const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); const openDevtools = async (page, client) => { const frameId = page.mainFrame()._id; const { url: inspectUrl } = await client.send('Page.inspect', { frameId }); exec(`"${chromeExecutable}" "${inspectUrl}"`, error => { if (error) throw new Error('Unable to open devtools: ' + error); }); await delay(5000); }; const page = await browser.newPage(); const client = await page.target().createCDPSession(); await openDevtools(page, client); await page.goto('http://example.com'); ``` ## Session Limits & Timeouts * **Single Navigation Per Session:** You can **load one site per session**. After that, interact freely via **clicks, scrolling, and JS execution**. * **Idle Timeout:** Sessions inactive for **5 minutes** auto-close. * **Max Session Length:** Sessions expire after **30 minutes** to prevent abuse. ## Run Your Script ```sh theme={null} node script.js ``` ```sh theme={null} python main.py ``` ## Final Thoughts BrowserAI is built for **serious automation** — **no CAPTCHAs, no blocks, no rate limits**. Whether you're scraping at scale or automating workflows, **this is the browser you actually need.** # BrowserAI FAQ Source: https://docs.browser.ai/general/faqs Whether you're just getting started with BrowserAI or diving into advanced features, this FAQ covers everything from session handling and country targeting to performance tips, error codes, pricing, and more. Explore solutions, best practices, and helpful insights to make the most of your BrowserAI experience. **Nope!** BrowserAI is designed for **single-page navigation per session**. What this means: * You can **navigate within a page** (clicks, scrolling, interactions). * But **you can't load a second domain** within the same session. **Solution?** If you need to load multiple pages, spawn a new session for each URL. * **Idle sessions** (no interaction) auto-close after 5 minutes. * **Max session duration:** 30 minutes. After that, your session will time out. The **Change Location** feature lets you adjust your BrowserAI’s geographic location for accurate geo-targeted scraping and content testing. You can change the location by: 1. Updating the `{"country":"XX"}` field in the **API Token** tab. 2. Replacing `country-us` in the **Headless Browser** tab with your desired country code.
**Want all of Europe?**\ Use `-country-eu` to dynamically select an EU-based IP. **Heads-up:** For bot-heavy websites, manually selecting a country may actually decrease success rates. Let BrowserAI handle it automatically when possible!
BrowserAI is battle-tested for web automation and supports: * **Puppeteer (Node.js).** * **Playwright (Node.js, Python, C#).** * **Selenium (Java, Python, C#, Node.js, Go, Ruby).** **Supported environments:** | Language | Puppeteer | Playwright | Selenium | | :---------- | :--------------- | :---------------- | :--------------- | | **Node.js** | ✅ Native | ✅ Native | ✅ WebDriverJS | | **Python** | ❌ | ✅ Native | ✅ WebDriver | | **Java** | ✅ Puppeteer-Java | ✅ Playwright-Java | ✅ Native | | **C#** | ✅ PuppeteerSharp | ✅ Playwright-.NET | ✅ WebDriver | | **Go** | ❌ | ✅ Playwright-Go | ✅ WebDriver-Go | | **Ruby** | ✅ Puppeteer-Ruby | ✅ Playwright-Ruby | ✅ WebDriver-Ruby | Need **visual proof** of what's happening in your session? Capture a **screenshot** at any time: ```js Puppeteer theme={null} await page.screenshot({ path: 'screenshot.png', fullPage: true }); ``` ```python Playwright theme={null} await page.screenshot(path='screenshot.png', full_page=True) ``` Some websites have **complex anti-bot measures**, which require extra processing to **bypass protections**. **To ensure smooth navigation, increase the timeout threshold:** ```js Puppeteer theme={null} // Navigate to site with 2 min timeout page.goto('', { timeout: 2*60*1000 }); ``` ```python Playwright theme={null} # Navigate to site with 2 min timeout page.goto('', timeout=2*60*1000) ``` ```cs PuppeteerSharp theme={null} // Navigate to site with 2 min timeout await page.GoToAsync("https://example.com", new NavigationOptions() { Timeout = 2*60*1000, }); ``` Always set a higher timeout\*\*(2+ minutes)\*\* for bot-protected websites. If you're getting **connection issues**, run the following **cURL test**: ```sh theme={null} curl -v -u USER:PASS https://brd.superproxy.io:9222/json/protocol ``` If you get JSON in response: ✅ **You're successfully connected.**\ If no JSON appears: ❌ **Check your credentials & network settings.** | Error Code | Meaning | How to Fix | | ---------- | ------------------------ | -------------------------------------------- | | **403** | Authentication issue | Check credentials & correct API zone. | | **407** | Proxy connection failure | Verify proxy settings & remote browser port. | | **503** | Service unavailable | Try again in 1-2 minutes. | Simple: **You pay per GB of data transferred**. * No per-instance fees * No hourly costs * No extra charges for specific countries However, certain **Premium Domains** may have additional costs due to **extra unblocking measures**.
# Welcome to BrowserAI Source: https://docs.browser.ai/general/intro Automate. Scrape. Scale. Without Getting Blocked. BrowserAI is a **serverless, unblockable browser** built for large-scale web automation and data extraction. Say goodbye to **CAPTCHAs, IP bans, and complex proxy configurations**—BrowserAI **handles bot detection challenges for you**, so you can focus on data collection. Websites track unique browser fingerprints to detect bots. We make sure your AI agents look and behave like real users. No more getting stuck on CAPTCHAs—we handle them automatically so your automation keeps running smoothly. Easily switch user agents to match different browsers, devices, or platforms—whatever your task requires. Customize referral headers to make your requests look natural and avoid unnecessary scrutiny. Store, manage, and send cookies just like a real browser, so your AI agents stay logged in and undetected. If a request fails or gets blocked, we’ll retry it with a fresh IP—no extra effort needed. Render dynamic content, interact with JavaScript-heavy sites, and scrape data that simple requests can’t reach. We check responses for accuracy and consistency, so your AI agents don’t waste time on bad data. BrowserAI is your **invisible automation assistant**, allowing you to **collect data at scale, without getting blocked**. # First steps with BrowserAI Source: https://docs.browser.ai/general/start Effortless setup. Seamless automation. No roadblocks. This guide will walk you through launching your first task in **BrowserAI** in just a few steps—so you can start automating browser interactions at scale **without worrying about anti-bot restrictions like fingerprinting, CAPTCHAs, or IP blocks**. ### Quick Start [Sign up](https://browser.ai/dashboard/page/projects) to BrowserAI. Navigate to the **Live chat** section on the left sidebar and start a new conversation. Just say what you're aiming to do, the kind of info you're looking for, or the task you want to complete. **Be sure to clearly define the task you're looking to accomplish** — providing detailed information will help BrowserAI deliver the most precise and relevant results. BrowserAI will split your main task into several smaller sub-tasks to make it easier to achieve. You can tweak, remove, or add more sub-tasks as you like. Once you're happy with it, just go ahead and approve it by pressing **Run session**. On your right, you'll find a **live browser window** that shows your session in action and how things are moving along. After the task is finished, you'll be able to download a ready-to-use JSON file containing all the parameters and information you requested by pressing **Download JSON**! Feel free to explore our **API** for quick [task creation](https://docs.browser.ai/api-reference/endpoint/tasks), [metadata retrieval](https://docs.browser.ai/api-reference/endpoint/taskMetadata), and seamless [access to task results](https://docs.browser.ai/api-reference/endpoint/results). # Browser.AI Errors Troubleshooting Source: https://docs.browser.ai/general/troubleshooting Explore the catalog of Browser.AI HTTP errors, including error codes and descriptions. | **Error Code** | **Error Type** | **Description** | | -------------- | -------------- | -------------------------------------------------------------------- | | 1100 | compile\_error | ReferenceError: pag is not defined | | 1200 | engine\_error | BrowserType.connect\_over\_cdp: Timeout 30000ms exceeded | | 1300 | ai\_error | OpenAI API version 2025-01-01-preview have exceeded token rate limit | | 1400 | network\_error | "networkidle" event fired | | 1500 | auth\_error | 403 Auth Failed (wrong\_customer\_name) | | 1600 | unknown\_error | ... | # Captcha Handling Source: https://docs.browser.ai/headless-browser/captcha-solver By default, BrowserAI automatically solves CAPTCHAs as part of its proxy unblocking system, ensuring seamless requests. The CAPTCHA solver automatically detects and solves CAPTCHA challenges during scraping at no extra cost, ensuring seamless data extraction. CAPTCHA solving, offering a lightweight, flexible solution for broader scraping scenarios where full automation isn’t required. Best for: * Scraping data without getting blocked. * Emulating real-user behavior for stealthy automation. * Teams without an unblocking system that want to skip automatic CAPTCHA solving. ## How to enable Captcha Handler To enable Captcha Handler in your BrowserAI project: 1. Go to your [project](https://browser.ai/dashboard/page/projects). 2. Head to **Headless Browser** tab on the right toolbar. 3. Scroll down to Configuration -> Basic settings -> **Captcha Solver**. To manually configure the default CAPTCHA solver using CDP commands, refer to the [**CDP functions**](https://docs.browser.ai/cdp-func/standard) for full control over the solving process. # CDP Functions Source: https://docs.browser.ai/headless-browser/cdp-func Unlock the full potential of browser.ai with CDP integration, enabling seamless control over browser automation. From cookie management to precise geo-targeting, BrowserAI empowers developers to optimize web scraping workflows using familiar Puppeteer and Playwright commands. ## Standard Functions BrowserAI is fully **CDP-compatible**, meaning every **Puppeteer function and feature** works right out of the box. You can explore the complete Puppeteer API in the [official Puppeteer docs](https://pptr.dev/). But we didn’t stop there—we’ve added **custom CDP functions**, fine-tuned for high-performance scraping and stealth browsing. Take full control of your automation stack and push the limits of what’s possible. The following are a few common browser navigation functions to get you started. ```js NodeJS - Puppeteer theme={null} const page = await browser.newPage(); await page.goto('https://example.com'); const html = await page.content(); ``` **More info:** [Puppeteer Page Content API](https://pptr.dev/api/puppeteer.page.content) ```js NodeJS - Puppeteer theme={null} const page = await browser.newPage(); await page.goto('https://example.com'); await page.click('a[href]'); ``` **More info:** [Puppeteer Click API](https://pptr.dev/api/puppeteer.page.click) ```js Puppeteer theme={null} await page.screenshot({ path: 'screenshot.png', fullPage: true }); ``` ```python Playwright theme={null} await page.screenshot(path='screenshot.png', full_page=True) ``` ```cs PuppeteerSharp theme={null} await page.ScreenshotAsync("screenshot.png", new () { FullPage = true }); ``` The example scripts above will save the screenshot as **screenshot.png** in your files. You might need to scroll the viewport to the bottom at times, such as when activating 'infinite scroll'. Here's how: ```js NodeJS - Puppeteer theme={null} const page = await browser.newPage(); await page.goto('https://example.com'); await page.evaluate(() => window.scrollBy(0, window.innerHeight)); ``` It is possible to block endpoints that are not required to save bandwidth. See an example of this below: ```js NodeJS - Puppeteer theme={null} const blockedUrls = ['*doubleclick.net*']; const page = await browser.newPage(); const client = await page.target().createCDPSession(); await client.send('Network.enable'); await client.send('Network.setBlockedURLs', { urls: blockedUrls }); await page.goto('https://washingtonpost.com'); ``` Please note that this is supported only for customers who completed the **KYC verification process**. ```js NodeJS - Puppeteer theme={null} const page = await browser.newPage(); await page.setCookie({ name: 'LANG', value: 'en-US', domain: 'example.com' }); await page.goto('https://example.com'); ``` **More info:** [Puppeteer Set Cookie API](https://pptr.dev/api/puppeteer.page.setcookie) When using the BrowserAI, the same **country-targeting** parameter is available to use as in our other proxy products. When setting up your script, add the `-country` flag, **after** your "USER" credentials, followed by the 2-letter [ISO code](https://www.nationsonline.org/oneworld/country_code_list.htm) for that country. ```js theme={null} const SBR_WS_ENDPOINT = `wss://${USER-country-us:PASS}@brd.superproxy.io:9222`; ``` #### **EU Region** You can target the entire European Union region in the same manner as "Country" above by adding "eu" after "country" in your request: `-country-eu` Requests sent using `-country-eu` will use IPs from **one** of the countries below which are included automatically within "eu": ```sh Countries theme={null} AL, AZ, KG, BA, UZ, BI, XK, SM, DE, AT, CH, UK, GB, IE, IM, FR, ES, NL, IT, PT, BE, AD, MT, MC, MA, LU, TN, DZ, GI, LI, SE, DK, FI, NO, AX, IS, GG, JE, EU, GL, VA, FX, FO ``` The allocation of a country within the EU is **random**. ## Custome Functions ### Captcha Solver BrowserAI’s **built-in CAPTCHA solver automatically handles all CAPTCHAs**, keeping your automation uninterrupted. Use custom CDP functions to monitor and fine-tune the solving process directly in your code. If you would like to disable CAPTCHA solver entirely through the Control Panel see our feature for [Disable Captcha Solver](/scraping-automation/scraping-browser/features/captcha-solver). Once a CAPTCHA is solved, BrowserAI automatically submits the form if required. ### CAPTCHA Solver - Automatic Solve Use this command to return the status after the captcha was solved, failed, or not detected. ```js Captcha.solve theme={null} Captcha.solve({ detectTimeout?: number // Detect timeout in millisecond for solver to detect captcha options?: CaptchaOptions[] // Configuration options for captcha solving }) : SolveResult ``` ```js SolveResult theme={null} SolveResult : { status: SolveStatus // Detect and solve status type?: string // Detected captcha type error?: string // Error if captcha was not solved } ``` ```js SolveStatus theme={null} SolveStatus : string enum { "not_detected" // Captcha was not detected "solve_finished" // Captcha successfully solved "solve_failed" // Captcha detected, but was not solved "invalid" // Something goes wrong } ``` **Examples** ```js Puppeteer theme={null} const page = await browser.newPage(); const client = await page.target().createCDPSession(); await page.goto('[https://site-with-captcha.com](https://site-with-captcha.com/)'); // Note 1: If no captcha was found it will return not_detected status after detectTimeout // Note 2: Once a CAPTCHA is solved, if there is a form to submit, it will be submitted by default const client = await page.target().createCDPSession(); const {status} = await client.send('Captcha.solve', {detectTimeout: 30*1000}); console.log(`Captcha solve status: ${status}`) ``` ```python Playwright theme={null} page = await browser.new_page() client = await page.context.new_cdp_session(page) await page.goto('[https://site-with-captcha.com](https://site-with-captcha.com/)') # Note 1: If no captcha was found it will return not_detected status after detectTimeout # Note 2: Once a CAPTCHA is solved, if there is a form to submit, it will be submitted by default client = await page.context.new_cdp_session(page) solve_result = await client.send('Captcha.solve', { 'detectTimeout': 30*1000 }) status = solve_result['status'] print(f'Captcha solve status: {status}') ``` If CAPTCHA-solving fails, retry the process. If the issue persists, submit a support request with details of the problem for further assistance. Use the following functions to identify specific stages in the CAPTCHA-solving process and debug more effectively.: | | | | ----------------------- | -------------------------------------------------------------- | | `Captcha.detected` | browser.ai has encountered a CAPTCHA and has begun to solve it | | `Captcha.solveFinished` | browser.ai successfully solved the CAPTCHA | | `Captcha.solveFailed` | browser.ai failed in solving the CAPTCHA | | `Captcha.waitForSolve` | browser.ai waits for CAPTCHA solver to finish | **Examples** The following code sets up a CDP session, listens for CAPTCHA events, and handles timeouts: ```js Puppeteer theme={null} // Node.js - Puppeteer - waiting for CAPTCHA solving events const client = await page.target().createCDPSession(); await new Promise((resolve, reject)=>{client.on('Captcha.solveFinished', resolve); client.on('Captcha.solveFailed', ()=>reject(new Error('Captcha failed'))); setTimeout(reject, 5 * 60 * 1000, new Error('Captcha solve timeout'));}); ``` ```python Playwright theme={null} # Python - Playwright - waiting for CAPTCHA solving events client = await page.context.new_cdp_session(page) client.on('Captcha.detected', lambda c: print('Captcha detected', c)) client.on('Captcha.solveFinished', lambda _: print('Captcha solved!')) client.on('Captcha.solveFailed', lambda _: print('Captcha failed!')) ``` Selenium doesn't support asynchronous server-driven events like Puppeteer and Playwright. The `Captcha.waitForSolve` command waits for BrowserAI's CAPTCHA solver to finish. ```python Python - Selenium theme={null} # Python Selenium - Waiting for Captcha to auto-solve after navigate driver.execute('executeCdpCommand', { 'cmd': 'Captcha.waitForSolve', 'params': {}, }) ``` ### CAPTCHA Solver - Manual Control To manually configure or disable the default CAPTCHA solver—allowing you to call it manually or handle solving yourself—use the following CDP commands and settings. This command is used to control the auto-solving of a CAPTCHA. You can disable auto-solve or configure algorithms for different CAPTCHA types and manually trigger this: ```js Captcha.setAutoSolve theme={null} Captcha.setAutoSolve({ autoSolve: boolean // Whether to automatically solve captcha after navigate options?: CaptchaOptions[] // Configuration options for captcha auto-solving }) : void ``` ```js CaptchaOptions theme={null} CaptchaOptions : { type: string // Captcha type disabled?: boolean // Disable detect and solve for specified captcha ... // additinal options related to captcha type } ``` Examples of CDP commands to disable auto-solver **completely** within the session: ```js Puppeteer theme={null} // Node.js Puppeteer - Disable Captcha auto-solver completely const page = await browser.newPage(); const client = await page.target().createCDPSession(); await client.send('Captcha.setAutoSolve', { autoSolve: false }); ``` ```python Playwright theme={null} # Python Playwright - Disable Captcha auto-solver completely page = await browser.new_page() client = await page.context.new_cdp_session(page) await client.send('Captcha.setAutoSolve', {'autoSolve': False}) ``` ```python Selenium theme={null} # Python Selenium - Disable Captcha auto-solver completely driver.execute('executeCdpCommand', { 'cmd': 'Captcha.setAutoSolve', 'params': {'autoSolve': False}, }) ``` ```js Puppeteer theme={null} // Node.js Puppeteer - Disable Captcha auto-solver for ReCaptcha only const page = await browser.newPage(); const client = await page.target().createCDPSession(); await client.send('Captcha.setAutoSolve', { autoSolve: true, options: [{ type: 'usercaptcha', disabled: true, }], }); ``` ```python Playwright theme={null} # Python Playwright - Disable Captcha auto-solver for ReCaptcha only page = await browser.new_page() client = await page.context.new_cdp_session(page) await client.send('Captcha.setAutoSolve', { 'autoSolve': True, 'options': [{ 'type': 'usercaptcha', 'disabled': True, }], }) ``` ```js Puppeteer theme={null} // Node.js Puppeteer - manually solving CAPTCHA after navigation const page = await browser.newPage(); const client = await page.target().createCDPSession(); await client.send('Captcha.setAutoSolve', { autoSolve: false }); await page.goto('https://site-with-captcha.com', { timeout: 2*60*1000 }); const {status} = await client.send('Captcha.solve', { detectTimeout: 30*1000 }); console.log('Captcha solve status:', status); ``` ```python Playwright theme={null} # Python Playwright - manually solving CAPTCHA after navigation page = await browser.new_page() client = await page.context.new_cdp_session(page) await client.send('Captcha.setAutoSolve', {'autoSolve': False}) await page.goto('https://site-with-captcha.com', timeout=2*60_000) solve_result = await client.send('Captcha.solve', {'detectTimeout': 30_000}) print('Captcha solve status:', solve_result['status']) ``` ```python Selenium theme={null} # Python Selenium - manually solving CAPTCHA after navigation driver.execute('executeCdpCommand', { 'cmd': 'Captcha.setAutoSolve', 'params': {'autoSolve': False}, }) driver.get('https://site-with-captcha.com') solve_result = driver.execute('executeCdpCommand', { 'cmd': 'Captcha.solve', 'params': {'detectTimeout': 30_000}, }) print('Captcha solve status:', solve_result['value']['status']) ``` For the following three CAPTCHA types we support the following additional options to control and configure our auto-solving algorithm. ```js CF Challenge theme={null} timeout: 40000 selector: '#challenge-body-text, .challenge-form' check_timeout: 300 error_selector: '#challenge-error-title' success_selector: '#challenge-success[style*=inline]' check_success_timeout: 300 btn_selector: '#challenge-stage input[type=button]' cloudflare_checkbox_frame_selector: '#turnstile-wrapper iframe' checkbox_area_selector: '.ctp-checkbox-label .mark' wait_timeout_after_solve: 500 wait_networkidle: {timeout: 500} ``` ```js HCaptcha theme={null} detect_selector: '#cf-hcaptcha-container, #challenge-hcaptcha-wrapper .hcaptcha-box, .h-captcha' pass_proxy: true submit_form: true submit_selector: '#challenge-form body > form[action*="internalcaptcha/captchasubmit"] value_selector: '.h-captcha textarea[id^="h-captcha-response"]' ``` ```js UserCaptcha (reCAPTCHA) theme={null} { // configuration keys and default values for reCAPTCHA (type=usercaptcha) type: 'usercaptcha', // selector to retrieve sitekey and/or action selector: '.g-recaptcha, .recaptcha', // attributes to search for sitekey sitekey_attributes: ['data-sitekey', 'data-key'], // attributes to search for action action_attributes: ['data-action'], // detect selectors detect_selector: ` .g-recaptcha[data-sitekey] > *, .recaptcha > *, iframe[src*="[www.google.com/recaptcha/api2](http://www.google.com/recaptcha/api2)"], iframe[src*="[www.recaptcha.net/recaptcha/api2](http://www.recaptcha.net/recaptcha/api2)"], iframe[src*="[www.google.com/recaptcha/enterprise](http://www.google.com/recaptcha/enterprise)"]`, // element to type response code into reponse_selector: '#g-recaptcha-response, .g-recaptcha-response', // should solver submit form automatically after captcha solved submit_form: true, // selector for submit button submit_selector: '[type=submit]', } ``` ### Emulation Functions Use this command to get a list of all possible devices that can be emulated. This function returns an array of device options that can be used with the setDevice command. ```js Example theme={null} Emulation.getSupportedDevices().then(devices => { console.log(devices);}); ``` After retrieving the list of supported devices, you can emulate a specific device using the Emulation.setDevice command. This adjusts the screen width, height, userAgent, and devicePixelRatio to match the selected device. ```js Usage theme={null} Emulation.setDevice({device: '[device_name]'}); ``` ```js Example theme={null} Emulation.setDevice({device: 'iPhone X'}); ``` ## Landscape mode If you wish to change the orientation to landscape (for devices that support it), add the string `landscape` after the `device_name`. ```js Example theme={null} Emulation.setDevice({device: 'iPhone X landscape'}); ``` ### Custom Client SSL/TLS Certificates Use this command to **install custom client SSL/TLS certificates** for domain authentication when required. These certificates remain active for the **current BrowserAI session** and are automatically removed when the session ends. ```javascript theme={null} Browser.addCertificate(params: { cert: string // base64 encoded certificate file pass: string // password for the certificate }) : void ``` * Replace placeholder values `USER:PASS` with your valid BrowserAI credentials. * Replace `client.pfx` with the actual path to your certificate file. This file should be a valid SSL/TLS client certificate in .pfx format. * Replace `secret` with the actual password for the certificate. ```js NodeJS - Puppeteer theme={null} const puppeteer = require('puppeteer-core'); const fs = require('fs/promises'); const { AUTH = 'USER:PASS', TARGET_URL = 'https://example.com', CERT_FILE = 'client.pfx', CERT_PASS = 'secret', } = process.env; async function scrape(url = TARGET_URL, file = CERT_FILE, pass = CERT_PASS) { if (AUTH == 'USER:PASS') { throw new Error(`Provide BrowserAI credentials in AUTH` + ` environment variable or update the script.`); } console.log(`Connecting to Browser...`); const browserWSEndpoint = `wss://${AUTH}@brd.superproxy.io:9222`; const browser = await puppeteer.connect({ browserWSEndpoint }); try { console.log(`Connected! Installing ${file} certificate...`); const page = await browser.newPage(); const client = await page.createCDPSession(); const cert = (await fs.readFile(CERT_FILE)).toString('base64'); await client.send('Browser.addCertificate', { cert, pass }); console.log(`Installed! Navigating to ${url}...`); await page.goto(url, { timeout: 2 * 60 * 1000 }); console.log(`Navigated! Scraping page content...`); const data = await page.content(); console.log(`Scraped! Data: ${data}`); } finally { await browser.close(); } } scrape(); ``` ```python Python - Selenium theme={null} from os import environ from base64 import standard_b64encode from selenium.webdriver import Remote, ChromeOptions as Options from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection as Connection AUTH = environ.get('AUTH', default='USER:PASS') TARGET_URL = environ.get('TARGET_URL', default='https://example.com') CERT_FILE = environ.get('CERT_FILE', default='client.pfx') CERT_PASS = environ.get('CERT_PASS', default='secret') def scrape(url=TARGET_URL, file=CERT_FILE, pswd=CERT_PASS): if AUTH == 'USER:PASS': raise Exception('Provide BrowserAI credentials in AUTH ' 'environment variable or update the script.') print('Connecting to Browser...') server_addr = f'https://{AUTH}@brd.superproxy.io:9515' connection = Connection(server_addr, 'goog', 'chrome') driver = Remote(connection, options=Options()) try: print(f'Connected! Installing {file} certificate...') with open(file, 'rb') as f: cert = standard_b64encode(f.read()).decode() driver.execute('executeCdpCommand', { 'cmd': 'Browser.addCertificate', 'params': {'cert': cert, 'pass': pswd}, }) print(f'Installed! Navigating to {url}...') driver.get(url) print('Navigated! Scraping page content...') data = driver.page_source print(f'Scraped! Data: {data}') finally: driver.quit() scrape() ``` # Change Location Source: https://docs.browser.ai/headless-browser/geolocation Changing Location feature enables you to dynamically adjust your proxy’s geographic location within a specified region. It’s perfect for geo-targeted data collection, regional content testing, and simulating user behavior from various locations. This ensures accurate scraping, localization testing, and access to location-restricted content across different geographic regions. In the **Headless Browser** tab, update the 2-letter country code in the command by replacing `country-us` with your desired country. # Logging in to Forms Using BrowserAI Source: https://docs.browser.ai/headless-browser/log-in Learn how to securely automate login processes with BrowserAI, including KYC prerequisites and handling OTP verification. ### Workflow & Requirements To automate logging in to websites with BrowserAI, please be aware of the requirements and proper workflow, especially when handling multifactor authentication. ### Automated Login Process BrowserAI **can automate standard login flows** in your tasks. However, if an **OTP** (One-Time Password), such as an SMS code, is required during the login process, you must follow a two-step approach: * Open the target website and navigate to the login form. * Enter the username and password credentials. * Use the [`/tasks` API endpoint](https://docs.browser.ai/api-reference/endpoint/tasks) to retrieve the corresponding `execution_id`. * Once you receive the OTP (for example, via SMS), you need to provide this code to BrowserAI. You have **3 minutes** to submit the OTP code as an instruction before the task is **canceled!** * Submit the OTP as a new instruction for the same task by using the [`/instructions` API endpoint](https://docs.browser.ai/api-reference/endpoint/addInstructions). * This step allows BrowserAI to complete the authentication and proceed with your original workflow. Signing in to login forms using BrowserAI **requires successful completion of KYC** procedure before any activity can be performed. *** If you have any questions or require further guidance, please refer to the API documentation or [contact the BrowserAI team](mailto:hello@browser.ai) for support.