Interaction Functions


This article lists and explains the available commands within the Interaction code for writing a scraper using the IDE.

Commands marked with a star are proprietary functions developed by Bright Data.



Mark the collector input as bad. Will prevent any crawl retries (error_code=bad_input)

bad_input('Missing search term');



Mark the page as failed because of the website refusing access (error_code=blocked)

blocked('Login page was shown');



The box of coordinates that describes the area of an element (relative to the page, not the browser viewport). Only the first element matched will be measured

let box = bounding_box('.product-list');
// box == {
//   top: 10,
//   right: 800,
//   bottom: 210,
//   left: 200,
//   x: 200,
//   y: 10,
//   width: 600,
//   height: 200,
// }
  • Selector: A valid CSS selector for the element



Returns current browser window size




Capture and replay graphql requests with changed variables

let q = capture_graphql({
    payload: {id: 'ProfileQuery'},
    // you may need to pass url opt as RegExp in case when
    // graphql endpoint is not "*/graphql" which is default value
    // url: /\bgraphql\b/ // default
let [first_query, first_response] = q.wait_captured();
let second = q.replay({
    variables: {other_id: 2},


let q = capture_graphql({
    payload: {id: 'ProfileQuery'},
    // you may need to pass url opt as RegExp in case when
    // graphql endpoint is not "*/graphql" which is default value
    // url: /\bgraphql\b/ // default
if (!q.is_captured())
let [first_query, first_response] = q.wait_captured();
let second = q.replay({
    variables: {other_id: 2},
  • options: Params to control graphql request to capture
    • url
    • payload



Click on an element (will wait for the element to appear before clicking on it)

// Click the closest match to the passed coordinates
// (relative to the page).
// For example, clicking the center pin in a map
let box = bounding_box('#map')
let center = {x: (box.left+box.right)/2, y: (};
click('.map-pin', {coordinates: center});
  • selector: Element selector



Popups can appear at any time during a crawl and it's not always clear when you should be waiting for or closing them. Add close_popup() at the top of your code to add a background watcher that will close the popup when it appears. If a popup appears multiple times, it will always be closed

close_popup('.popup', '.popup_close');
close_popup('iframe.with-popup', '.popup_close', {click_inside: 'iframe.with-popup'});
  • popup selector: A valid CSS selector
  • close selector: A valid CSS selector
  • options: click_inside: selector of parent iframe which contains close button selector



Adds a line of data to the dataset created by the crawler

collect(<data_line>[, <validate_fn>]);
collect({price: data.price});
collect(product, p=>{
    if (!p.title)
        throw new Error('Product is missing a title');
  • data_line: A object with the fields you want to collect
  • validate_fn: Optional function to check that the line data is valid



Log messages from the interaction code

console.log(1, 'brightdata', [1, 2], {key: value});
console.error(1, 'brightdata', [1, 2], {key: value});



Configure your crawl to run from a specific country

  • code: 2-character ISO country code



Mark a page as a dead link so you can filter it from your future collections (error_code=dead_page)

dead_page('Product was removed');



Detects a block on the page

detect_block({selector: '.foo'}, {exists: true});
detect_block({selector: '.bar'}, {has_text: 'text'});
detect_block({selector: '.baz'}, {has_text: /regex_pattern/});
  • resource: An object specifying the resource required for the detection
    • Selector
  • condition: An object specifying how the resource should be processed for detection
    • exists
    • has_text



Stop all event listeners on the page from running. track_event_listeners() must have been called first

disable_event_listeners(['hover', 'click']);
  • event_types: Specific event types that should be disabled



Check if an element exists on page, and return a boolean accordingly

el_exists('#example'); // => true
el_exists('.does_not_exist'); // => false
el_exists('.does_not_exist', 5e3); // => false (after 5 seconds)
  • selector: Valid CSS selector
  • timeout: Timeout duration to wait for the element to appear on the page



Check if element is visible on page

el_is_visible('.is_not_visible', 5e3); // false (after 5 seconds)
  • selector: Valid CSS selector
  • timeout: Timeout duration to wait for the element to be visible on the page



Add a comment in the page HTML. Can be used to embed metadata inside HTML snapshots.

embed_html_comment('trace-id: asdf123');
  • comment: Body of the comment



Assert the capability of the browser to render the given font family on the page

font_exists('Liberation Mono');



Force the page to stop making changes. This can be used to save the page in a particular state so page snapshots that run after crawl won't see a different page state than you see now. This command is experimental. If you see problems, please report them to support




hover on an element (will wait for the element to appear before hovering on it)

  • selector: Element selector



Influence the process of the HTML capturing

    coordinate_attributes: true,
  • options: An object which accepts options defining how HTML capturing should be processed
    • coordinate_attributes



Collect image data

let i = new Image('');
collect({image: i});
  • src: Image URL or data:image URI string



Global object available to the interaction code. Provided by trigger input or next_stage() calls




Global object available to the interaction code. Provided by trigger input or next_stage() calls

let {created} = job;



Load html and return Cheerio instance

let $$ = load_html('<p id="p1">p1</p><p id="p2">p2</p>');
collect({data: $$('#p2').text()});
  • html: Any HTML string



Scroll to the bottom of a list to trigger loading more items. Useful for lazy-loaded infinite-scroll sites

load_more('.search-results', {children: '.result-item', trigger_selector: '.btn-load-more', timeout: 10000});
  • selector: Selector for the element that contains the lazy-loaded items



Read a list of urls from a sitemap xml (supports sitemap indexes, and .gz compressed sitemaps. see examples.)


let {pages} = load_sitemap({url: ''});

let {children} = load_sitemap({url: ''});



Object with info about current location. Available fields: href

location.href; // ""



Collect price/money data

let p = new Money(10, 'USD');
collect({product_price: p});
  • value: Amount of money
  • currency: Currency code



Move the mouse to the specified (x,y) position

mouse_to(<x>, <y>);
mouse_to(0, 0);
  • x: Target x position
  • y: Target y position



Navigate the browser to a URL


// waits until DOM content loaded event is fired in the browser
navigate(<url>, {wait_until: 'domcontentloaded'}); 

// adds a referer to the navigation
navigate(<url>, {referer: <url>}); 

// the number of milliseconds to wait for. Default is 30000 ms
navigate(<url>, {timeout: 45000}); 

// Don't throw an error if this URL sends a 404 status code
navigate(<url>, {allow_status: [404]});

// Specify browser width/height
navigate(<url>, {
    fingerprint: {screen: {width: 400, height: 400}},
  • A 404 status code will throw a dead_page error by default. Use opt.allow_status to override this
  • url: A URL to navigate to
  • opt: navigate options (see examples)



Run the next stage of the crawler with the specified input

next_stage({url: '', page: 1});
  • input: Input object to pass to the next browser session



Parse the page data

let page_data = parse();
    title: page_data.title,
    price: page_data.price,



Preserve proxy session across children of this page




Type special characters like Enter or Backspace in the currently focused input (usually used after typing something in a search box)




Configure your crawl to run from a specific location. Unless you need high resolution control over where your crawl is running from, you probably want to use `country(code)` instead

proxy_location({country: 'us'});

// lat in range: [-85, 85], long in range: [-180, 180]
proxy_location({lat: 37.7749, long: 122.4194}); 

// radius in km
proxy_location({lat: 37.7749, long: 122.4194, country: 'US', radius: 100}); 
  • configuration: Object with a desired proxy location, check examples for more info



Returns history of URL redirects since last navigate

let redirects = redirect_history();
// returns:
// [
//   '',
//   '',
//   '',
// ]



Run this stage of the crawler again with new input

rerun_stage({url: ''});



Returns the final URL that the given url argument leads to

let {href} = parse().anchor_elem_data;
collect({final_url: resolve_url(href)});
  • url: URL string/instance



Returns the response headers of the last page load

let headers = response_headers();
console.log('content-type', headers['content-type']);



Make a direct HTTP request

let res = request('');
let res = request({url: '', method: 'POST', headers: {'Content-type': 'application/json'}, body: {hello: 'world'}})
  • url | options: the url to make the request to, or request options (see examples)



The same as click but use right mouse button instead (will wait for the element to appear before clicking on it)

  • selector: Element selector



Run a specific stage of the crawler with a new browser session

run_stage(2, {url: '', page: 1});
  • stage: Which stage to run (1 is first stage)
  • input: Input object to pass to the next browser session



Scroll the page so that an element is visible.If you're doing this to trigger loading some more elements from a lazy loaded list, use load_more(). Defaults to scrolling in a natural way, which may take several seconds. If you want to jump immediatley, use {immediate: true}

scroll_to('top'); // scroll to the top of the page
scroll_to('bottom'); // scroll to the bottom of the page
scroll_to('top', {immediate: true}); // jump to top of page immediately
  • selector: Selector of the element you want to scroll to



Scroll through the page so that all the elements matching the selector will be visible on screen

  • selector: Selector of the elements you want to scroll through



Pick a value from a select element

select(<select>, <value>);
select('#country', 'Canada');
  • selector: Element selector



An array of lines to add to your dataset at the end of this page crawl. Each call to set_lines() will override previous ones, and only the last set of lines will be added into the dataset (tracked per page crawl). This is a good fit when the collector is set to collect partial on errors. You can keep calling set_lines() with the data you gathered so far, and the last call will be used if the page crawl throws an error

set_lines(<data_line>[, <validate_fn>]);
set_lines(products_so_far, i=>{
    if (!i.price)
        throw new Error('Missing price');
  • lines: An array of data lines to add to your final dataset
  • validate_fn: Optional function to check that the line data is valid (run once per line)



Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist

set_session_cookie(<domain>, <name>, <value>);



Set extra headers for all the HTTP requests

set_session_headers({'HEADER_NAME': 'HEADER_VALUE'});
  • headers: Object with extra headers in key-value format



Solve any captchas shown on the page

solve_captcha({type: 'simple', selector: '#image', input: '#input'});



Returns the status code of the last page load

collect({status_code: status_code()});



Save the responses from all browser request that match

tag_all_responses(<field>, <pattern>, <options>);
tag_all_responses('resp', /url/, {jsonp: true});
tag_all_responses('resp', /url/, {allow_error: true});
tag_all_responses('profiles', /\/api\/profile/);
let profiles = parse().profiles;
for (let profile of profiles)
  • field: The name of the tagged field
  • pattern: The URL pattern to match
  • options: Set options.jsonp=true to parse response bodies that are in jsonp format. This will be automatically detected when possible



Allows to get files downloaded by browser

        let SEC = 1000;
        let download = tag_download(/\/foo\/bar/);
        let file1 = download.next_file({timeout: 10*SEC});
        let file2 = download.next_file({timeout: 20*SEC});
        collect({file1, file2});
  • url: A pattern or a string to match requests against



Save the image url from an element

tag_image(field, selector);
tag_image('image', '#product-image');
  • field: The name of the tagged field
  • selector: A valid CSS selector



Save the response data from a browser request

tag_response(<field>, <pattern>, <options>);
tag_response('resp', /url/, {jsonp: true});
tag_response('resp', /url/, {allow_error: true});
tag_response('resp', (req, res)=>{
            if (req.url.includes('/api/'))
                let request_body = req.body;
                let request_headers = req.headers;
                let response_body = res.body;
                let response_headers = res.headers;

tag_response('teams', /\/api\/teams/);
let teams = parse().teams;
for (let team of teams)
  • name: The name of the tagged field
  • pattern: The URL pattern to match
  • options: Set options.jsonp=true to parse response bodies that are in jsonp format. This will be automatically detected when possible



Save a screenshot of the page HTML

enshot(<field>, <options>);
tag_screenshot('html_screenshot', {filename: 'screen'});
tag_screenshot('view', {full_page: false}); // full_page defaults to true
  • field: The name of the tagged field
  • options: Download options (see example)



Extract some JSON data saved in a script on the page

tag_script(<field>, <selector>);
tag_script('teams', '#preload-data');
tag_script('ssr_state', '#__SSR_DATA__');
  • name: The name of the tagged script
  • selector: The selector of the script to tag



Parse the current page as a search engine result page

tag_serp('serp_bing_results', 'bing')
tag_serp('serp_google_results', 'google')
  • field: The name of the tagged field
  • type: Parser type: (e.g. bing, google)



Save the video url from an element

tag_video(field, selector);
tag_video('video', '#product-video', {download: true});
  • field: The name of the tagged field
  • selector: A valid CSS selector
  • opt: download options (see example)



Tag a javascript value from the browser page

tag_window_field(<field>, <key>);
tag_window_field('initData', '__INIT_DATA__');
  • field: The path to the relevant data



Start tracking the event listeners that the browser creates. It's needed to run disable_event_listeners() later




Enter text into an input (will wait for the input to appear before typing)

type(<selector>, <text>);
type('#location', 'New York');

// replacing text in input if it is not empty
type(<selector>, <text>, {replace: true}); 

// type text to an element with id ending "input-box" (e.g. <input id="c2E57-input-box">)
type('[id$=input-box]', <text>); 

// dispatching 'Enter' key press
type(<selector>, ['Enter']); 

// typing text and then dispatching 'Enter' key press
type(<selector>, ['Some text', 'Enter']); 

// deleting 1 char from input
type(<selector>, ['Backspace']); 
  • selector: Element selector
  • text: Text to enter



URL class from NodeJS standard "url" module

let u = new URL('');
  • url: URL string



Monitor failed requests with a callback function

verify_requests(({url, error, type, response})=>{
    if (response.status!=404 && type=='Font')
        throw new Error('Font failed to load');
  • callback: A function which will be called on each failed request with an object in format: {url, error, type, response}



Collect video data

let v = new Video('');
collect({video: v});
  • src: Video URL



Wait for an element to appear on the page

wait('.search-results .product');

// the number of milliseconds to wait for. Default is 30000 ms
wait(<selector>, {timeout: 5000}); 

// wait for element to be hidden
wait(<selector>, {hidden: true}); 

// wait for element inside in an iframe
wait(<selector>, {inside: '#iframe_id'}); 
  • selector: Element selector
  • opt: wait options (see examples)



Wait for any matching condition to succeed

wait_any(['#title', '#notfound']);



Wait for a parser field to contain a value. This can be useful after you click something to wait for some data to appear

wait_for_parser_value(<field>[, <validate_fn>][, opt]);
wait_for_parser_value('listings.0.price', v=>{
            return parseInt(v)>0;
        }, {timeout: 5000});
  • field: The parser value path to wait on
  • validate_fn: An optional callback function to validate that the value is correct
  • opt: Extra options (e.g. timeout)



Wait for an element on the page to include some text

wait_for_text(<selector>, <text>);
wait_for_text('.location', 'New York');
  • selector: Element selector
  • text: The text to wait for



Wait for an element to not be visible on the page (removed or hidden)

wait_hidden(<selector>, {timeout: 5000});
  • selector: Element selector



Wait the browser network has been idle for a given time

    timeout: 1e3,
    ignore: [/long_request/, ''],
  • timeout: Wait for browser network to be idle for X milliseconds
  • options: ignore: an array of patterns to exclude requests from monitoring timeout: how long the network needs to be idle in milliseconds (default 500)



Wait until no changes are being made on the DOM tree for a given time

    ignore: [<selector1>, <selector2>],
    idle_timeout: 1000,
  • timeout: Milliseconds to wait for no changes
  • options: An object, which can accept a ignore argument to exclude some elements from monitoring



Wait for an element to be visible on the page

wait_visible(<selector>, {timeout: 5000});
  • selector: Element selector



Helper for jQuery-like expressions

  • selector: Element selector



View pages as a mobile device. This command will change user agent and screen parameters (resolution and device pixel ratio)

emulate_device('iPhone X');
emulate_device('Pixel 2');
  • device: A string with the name of device
  • here is the full list of device names
    • Blackberry PlayBook
    • Blackberry PlayBook landscape
    • BlackBerry Z30
    • BlackBerry Z30 landscape
    • Galaxy Note 3
    • Galaxy Note 3 landscape
    • Galaxy Note II
    • Galaxy Note II landscape
    • Galaxy S III
    • Galaxy S III landscape
    • Galaxy S5
    • Galaxy S5 landscape
    • Galaxy S8
    • Galaxy S8 landscape
    • Galaxy S9+
    • Galaxy S9+ landscape
    • Galaxy Tab S4
    • Galaxy Tab S4 landscape
    • iPad
    • iPad landscape
    • iPad (gen 6)
    • iPad (gen 6) landscape
    • iPad (gen 7)
    • iPad (gen 7) landscape
    • iPad Mini
    • iPad Mini landscape
    • iPad Pro
    • iPad Pro landscape
    • iPad Pro 11
    • iPad Pro 11 landscape
    • iPhone 4
    • iPhone 4 landscape
    • iPhone 5
    • iPhone 5 landscape
    • iPhone 6
    • iPhone 6 landscape
    • iPhone 6 Plus
    • iPhone 6 Plus landscape
    • iPhone 7
    • iPhone 7 landscape
    • iPhone 7 Plus
    • iPhone 7 Plus landscape
    • iPhone 8
    • iPhone 8 landscape
    • iPhone 8 Plus
    • iPhone 8 Plus landscape
    • iPhone SE
    • iPhone SE landscape
    • iPhone X
    • iPhone X landscape
    • iPhone XR
    • iPhone XR landscape
    • iPhone 11
    • iPhone 11 landscape
    • iPhone 11 Pro
    • iPhone 11 Pro landscape
    • iPhone 11 Pro Max
    • iPhone 11 Pro Max landscape
    • iPhone 12
    • iPhone 12 landscape
    • iPhone 12 Pro
    • iPhone 12 Pro landscape
    • iPhone 12 Pro Max
    • iPhone 12 Pro Max landscape
    • iPhone 12 Mini
    • iPhone 12 Mini landscape
    • iPhone 13
    • iPhone 13 landscape
    • iPhone 13 Pro
    • iPhone 13 Pro landscape
    • iPhone 13 Pro Max
    • iPhone 13 Pro Max landscape
    • iPhone 13 Mini
    • iPhone 13 Mini landscape
    • JioPhone 2
    • JioPhone 2 landscape
    • Kindle Fire HDX
    • Kindle Fire HDX landscape
    • LG Optimus L70
    • LG Optimus L70 landscape
    • Microsoft Lumia 550
    • Microsoft Lumia 950
    • Microsoft Lumia 950 landscape
    • Nexus 10
    • Nexus 10 landscape
    • Nexus 4
    • Nexus 4 landscape
    • Nexus 5
    • Nexus 5 landscape
    • Nexus 5X
    • Nexus 5X landscape
    • Nexus 6
    • Nexus 6 landscape
    • Nexus 6P
    • Nexus 6P landscape
    • Nexus 7
    • Nexus 7 landscape
    • Nokia Lumia 520
    • Nokia Lumia 520 landscape
    • Nokia N9
    • Nokia N9 landscape
    • Pixel 2
    • Pixel 2 landscape
    • Pixel 2 XL
    • Pixel 2 XL landscape
    • Pixel 3
    • Pixel 3 landscape
    • Pixel 4
    • Pixel 4 landscape
    • Pixel 4a (5G)
    • Pixel 4a (5G) landscape
    • Pixel 5
    • Pixel 5 landscape
    • Moto G4
    • Moto G4 landscape

Was this article helpful?