A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://splash.readthedocs.org/en/latest/scripting-ref.html below:

Website Navigation


Splash Scripts Reference — Splash 3.5 documentation

splash object is passed to main function as a first argument; via this object a script can control the browser. Think of it as of an API to a single browser tab.

Attributes¶ splash.args¶

splash.args is a table with incoming parameters. It contains merged values from the orignal URL string (GET arguments) and values sent using application/json POST request.

For example, if you passed ‘url’ argument to a script using HTTP API, then splash.args.url contains this URL.

You can also access splash.args using second, optional args argument of the main function:

function main(splash, args)
    local url = args.url
    -- ...
end

The example above is the same as

function main(splash)
    local url = splash.args.url
    -- ...
end

Using either args or splash.args is the preferred way to pass parameters to Splash scripts. An alternative way is to use string formatting to build a script with variables embedded. There are two problems which make splash.args a better solution:

  1. data must be escaped somehow, so that it doesn’t break a Lua script;
  2. embedding variables makes it impossible to use script cache efficiently (see save_args and load_args arguments of the HTTP API).
splash.js_enabled¶

Enable or disable execution of JavaSript code embedded in the page.

Signature: splash.js_enabled = true/false

JavaScript execution is enabled by default.

splash.private_mode_enabled¶

Enable or disable browser’s private mode (incognito mode).

Signature: splash.private_mode_enabled = true/false

Private mode is enabled by default unless you pass flag --disable-private-mode at Splash startup. Note that if you disable private mode some of the browsing data may persist between requests (it doesn’t affect cookies though).

See also: How do I disable Private mode?.

splash.resource_timeout¶

Set a default timeout for network requests, in seconds.

Signature: splash.resource_timeout = number

Example - abort requests to remote resources if they take more than 10 seconds:

function main(splash)
    splash.resource_timeout = 10.0
    assert(splash:go(splash.args.url))
    return splash:png()
end

Zero or nil value means “no timeout”.

Request timeouts set in splash:on_request using request:set_timeout have a priority over splash.resource_timeout.

splash.images_enabled¶

Enable/disable images.

Signature: splash.images_enabled = true/false

By default, images are enabled. Disabling of the images can save a lot of network traffic (usually around ~50%) and make rendering faster. Note that this option can affect the JavaScript code inside page: disabling of the images may change sizes and positions of DOM elements, and scripts may read and use them.

Splash uses in-memory cache; cached images will be displayed even when images are disabled. So if you load a page, then disable images, then load a new page, then likely first page will display all images and second page will display some images (the ones common with the first page). Splash cache is shared between scripts executed in the same process, so you can see some images even if they are disabled at the beginning of the script.

Example:

function main(splash, args)
  splash.images_enabled = false
  assert(splash:go(splash.args.url))
  return {png=splash:png()}
end
splash.plugins_enabled¶

Enable or disable browser plugins (e.g. Flash).

Signature: splash.plugins_enabled = true/false

Plugins are disabled by default.

splash.request_body_enabled¶

Enable or disable storage of request content.

Signature: splash.request_body_enabled = true/false

By default Splash doesn’t keep bodies of each request in memory. It means that request content is not available in request.info and in HAR exports. To make request content available to a Lua script set splash.request_body_enabled = true.

Note that request body in request.info is not available in the callback splash:on_response_headers or in the request of the response returned by splash:http_get and splash:http_post.

splash.response_body_enabled¶

Enable or disable response content tracking.

Signature: splash.response_body_enabled = true/false

By default Splash doesn’t keep bodies of each response in memory, for efficiency reasons. It means that in splash:on_response callbacks response.body attribute is not available, and that response content is not available in HAR exports. To make response content available to a Lua script set splash.response_body_enabled = true.

Note that response.body is always available in splash:http_get and splash:http_post results, regardless of splash.response_body_enabled option.

To enable response content tracking per-request call request:enable_response_body in a splash:on_request callback.

splash.indexeddb_enabled¶

Enable or disable IndexedDB.

Signature: splash.indexeddb_enabled = true/false

IndexedDB is disabled by default. Use splash.indexeddb_enabled = true to enable it.

Note

Currently IndexedDB is disabled by default because there are issues with Splash WebKit’s implementation. Default value for this option may change to true in future.

splash.webgl_enabled¶

Enable or disable WebGL.

Signature: splash.webgl_enabled = true/false

WebGL is enabled by default. Use splash.webgl_enabled = false to disable it.

splash.http2_enabled¶

Enable or disable HTTP2.

Signature: splash.http2_enabled = true/false

HTTP2 support is disabled by default as the current implementation can cause problems (e.g. network 399 errors). Use splash.http2_enabled = true to enable it.

Methods¶ splash:go¶

Go to an URL. This is similar to entering an URL in a browser address bar, pressing Enter and waiting until page loads.

Signature: ok, reason = splash:go{url, baseurl=nil, headers=nil, http_method="GET", body=nil, formdata=nil}

Parameters:

Returns: ok, reason pair. If ok is nil then error happened during page load; reason provides an information about error type.

Async: yes, unless the navigation is locked.

Five types of errors are reported (ok can be nil in 5 cases):

  1. There is a network error: a host doesn’t exist, server dropped connection, etc. In this case reason is "network<code>". A list of possible error codes can be found in Qt docs. For example, "network3" means a DNS error (invalid hostname).
  2. Server returned a response with 4xx or 5xx HTTP status code. reason is "http<code>" in this case, i.e. for HTTP 404 Not Found reason is "http404".
  3. Navigation is locked (see splash:lock_navigation); reason is "navigation_locked".
  4. Splash can’t render the main page (e.g. because the first request was aborted) - reason is render_error.
  5. If Splash can’t decide what caused the error, just "error" is returned.

Error handling example:

local ok, reason = splash:go("http://example.com")
if not ok then
    if reason:sub(0,4) == 'http' then
        -- handle HTTP errors
    else
        -- handle other errors
    end
end
-- process the page

-- assert can be used as a shortcut for error handling
assert(splash:go("http://example.com"))

Errors (ok==nil) are only reported when “main” webpage request failed. If a request to a related resource failed then no error is reported by splash:go. To detect and handle such errors (e.g. broken image/js/css links, ajax requests failed to load) use splash:har or splash:on_response.

splash:go follows all HTTP redirects before returning the result, but it doesn’t follow HTML <meta http-equiv="refresh" ...> redirects or redirects initiated by JavaScript code. To give the webpage time to follow those redirects use splash:wait.

headers argument allows to add or replace default HTTP headers for the initial request. To set custom headers for all further requests (including requests to related resources) use splash:set_custom_headers or splash:on_request.

Custom headers example:

local ok, reason = splash:go{"http://example.com", headers={
    ["Custom-Header"] = "Header Value",
}})

User-Agent header is special: once used, it is kept for further requests. This is an implementation detail and it could change in future releases; to set User-Agent header it is recommended to use splash:set_user_agent method.

splash:wait¶

Wait for time seconds. When script is waiting browser continues processing the webpage.

Signature: ok, reason = splash:wait{time, cancel_on_redirect=false, cancel_on_error=true}

Parameters:

Returns: ok, reason pair. If ok is nil then the timer was stopped prematurely, and reason contains a string with a reason.

Async: yes.

Usage example:

-- go to example.com, wait 0.5s, return rendered html, ignore all errors.
function main(splash)
    splash:go("http://example.com")
    splash:wait(0.5)
    return {html=splash:html()}
end

By default wait timer continues to tick when redirect happens. cancel_on_redirect option can be used to restart the timer after each redirect. For example, here is a function that waits for a given time after each page load in case of redirects:

function wait_restarting_on_redirects(splash, time, max_redirects)
    local redirects_remaining = max_redirects
    while redirects_remaining > 0 do
        local ok, reason = self:wait{time=time, cancel_on_redirect=true}
        if reason ~= 'redirect' then
            return ok, reason
        end
        redirects_remaining = redirects_remaining - 1
    end
    return nil, "too_many_redirects"
end
splash:jsfunc¶

Convert JavaScript function to a Lua callable.

Signature: lua_func = splash:jsfunc(func)

Parameters:

Returns: a function that can be called from Lua to execute JavaScript code in page context.

Async: no.

Example:

function main(splash, args)
  local get_div_count = splash:jsfunc([[
  function () {
    var body = document.body;
    var divs = body.getElementsByTagName('div');
    return divs.length;
  }
  ]])
  splash:go(args.url)

  return ("There are %s DIVs in %s"):format(
    get_div_count(), args.url)
end

Note how Lua [[ ]] string syntax is helpful here.

JavaScript functions may accept arguments:

local vec_len = splash:jsfunc([[
    function(x, y) {
       return Math.sqrt(x*x + y*y)
    }
]])
return {res=vec_len(5, 4)}

Global JavaScript functions can be wrapped directly:

local pow = splash:jsfunc("Math.pow")
local twenty_five = pow(5, 2)  -- 5^2 is 25
local thousand = pow(10, 3)    -- 10^3 is 1000

Lua → JavaScript conversion rules:

Lua JavaScript string string number number boolean boolean table Object or Array, see below nil undefined Element DOM node

Lua strings, numbers, booleans and tables can be passed as arguments; they are converted to JS strings/numbers/booleans/objects. Element instances are supported, but they can’t be inside a Lua table.

Currently it is not possible to pass other Lua objects. For example, it is not possible to pass a wrapped JavaScript function or a regular Lua function as an argument to another wrapped JavaScript function.

By default Lua tables are converted to JavaScript Objects. To convert a table to an Array use treat.as_array.

JavaScript → Lua conversion rules:

JavaScript Lua string string number number boolean boolean Object table Array table, marked as array (see treat.as_array) undefined nil null "" (an empty string) Date string: date’s ISO8601 representation, e.g. 1958-05-21T10:12:00.000Z Node Element instance NodeList a tabl with Element instances function nil circular object nil host object nil

Function result is converted from JavaScript to Lua data type. Only simple JS objects are supported. For example, returning a function or a JQuery selector from a wrapped function won’t work.

Returning a Node (a reference to a DOM element) or NodeList instance (result of document.querySelectorAll) works though, but only if Node or NodeList is the only result - Nodes and NodeLists can’t be inside other objects or arrays.

Note

The rule of thumb: if an argument or a return value can be serialized via JSON, then it is fine. You can also return DOM Element or a NodeList, but they can’t be inside other data structures.

Note that currently you can’t return JQuery $ results and similar structures from JavaScript to Lua; to pass data you have to extract their attributes of interest as plain strings/numbers/objects/arrays:

-- this function assumes jQuery is loaded in page
local get_hrefs = splash:jsfunc([[
    function(sel){
        return $(sel).map(function(){return this.href}).get();
    }
]])
local hrefs = get_hrefs("a.story-title")

However, you can also write the code above using Element objects and splash:select_all:

local elems = splash:select_all("a.story-title")
local hrefs = {}
for i, elem in ipairs(elems) do
    hrefs[i] = elem.node:getAttribute("href")
end

Function arguments and return values are passed by value. For example, if you modify an argument from inside a JavaScript function then the caller Lua code won’t see the changes, and if you return a global JS object and modify it in Lua then object won’t be changed in webpage context. The exception is Element which has some mutable fields.

If a JavaScript function throws an error, it is re-throwed as a Lua error. To handle errors it is better to use JavaScript try/catch because some of the information about the error can be lost in JavaScript → Lua conversion.

See also: splash:runjs, splash:evaljs, splash:wait_for_resume, splash:autoload, treat.as_array, Element Object, splash:select, splash:select_all.

splash:evaljs¶

Execute a JavaScript snippet in page context and return the result of the last statement.

Signature: result = splash:evaljs(snippet)

Parameters:

Returns: the result of the last statement in snippet, converted from JavaScript to Lua data types. In case of syntax errors or JavaScript exceptions an error is raised.

Async: no.

JavaScript → Lua conversion rules are the same as for splash:jsfunc.

splash:evaljs is useful for evaluation of short JavaScript snippets without defining a wrapper function. Example:

local title = splash:evaljs("document.title")

Don’t use splash:evaljs when the result is not needed - it is inefficient and could lead to problems; use splash:runjs instead. For example, the following innocent-looking code (using jQuery) will do unnecessary work:

splash:evaljs("$(console.log('foo'));")

A gotcha is that to allow chaining jQuery $ function returns a huge object, splash:evaljs tries to serialize it and convert to Lua, which is a waste of resources. splash:runjs doesn’t have this problem.

If the code you’re evaluating needs arguments it is better to use splash:jsfunc instead of splash:evaljs and string formatting. Compare:

function main(splash)

    local font_size = splash:jsfunc([[
        function(sel) {
            var el = document.querySelector(sel);
            return getComputedStyle(el)["font-size"];
        }
    ]])

    local font_size2 = function(sel)
        -- FIXME: escaping of `sel` parameter!
        local js = string.format([[
            var el = document.querySelector("%s");
            getComputedStyle(el)["font-size"]
        ]], sel)
        return splash:evaljs(js)
    end

    -- ...
end

See also: splash:runjs, splash:jsfunc, splash:wait_for_resume, splash:autoload, Element Object, splash:select, splash:select_all.

splash:runjs¶

Run JavaScript code in page context.

Signature: ok, error = splash:runjs(snippet)

Parameters:

Returns: ok, error pair. When the execution is successful ok is True. In case of JavaScript errors ok is nil, and error contains the error string.

Async: no.

Example:

assert(splash:runjs("document.title = 'hello';"))

Note that JavaScript functions defined using function foo(){} syntax won’t be added to the global scope:

assert(splash:runjs("function foo(){return 'bar'}"))
local res = splash:evaljs("foo()")  -- this raises an error

It is an implementation detail: the code passed to splash:runjs is executed in a closure. To define functions use global variables, e.g.:

assert(splash:runjs("foo = function (){return 'bar'}"))
local res = splash:evaljs("foo()")  -- this returns 'bar'

If the code needs arguments it is better to use splash:jsfunc. Compare:

function main(splash)

    -- Lua function to scroll window to (x, y) position.
    function scroll_to(x, y)
        local js = string.format(
            "window.scrollTo(%s, %s);",
            tonumber(x),
            tonumber(y)
        )
        assert(splash:runjs(js))
    end

    -- a simpler version using splash:jsfunc
    local scroll_to2 = splash:jsfunc("window.scrollTo")

    -- ...
end

See also: splash:runjs, splash:jsfunc, splash:autoload, splash:wait_for_resume.

splash:wait_for_resume¶

Run asynchronous JavaScript code in page context. The Lua script will yield until the JavaScript code tells it to resume.

Signature: result, error = splash:wait_for_resume(snippet, timeout)

Parameters:

Returns: result, error pair. When the execution is successful result is a table. If the value returned by JavaScript is not undefined, then the result table will contain a key value that has the value passed to splash.resume(…). The result table also contains any additional key/value pairs set by splash.set(…). In case of timeout or JavaScript errors result is nil and error contains an error message string.

Async: yes.

Examples:

The first, trivial example shows how to transfer control of execution from Lua to JavaScript and then back to Lua. This command will tell JavaScript to sleep for 3 seconds and then return to Lua. Note that this is an async operation: the Lua event loop and the JavaScript event loop continue to run during this 3 second pause, but Lua will not continue executing the current function until JavaScript calls splash.resume().

function main(splash)

    local result, error = splash:wait_for_resume([[
        function main(splash) {
            setTimeout(function () {
                splash.resume();
            }, 3000);
        }
    ]])

    -- result is {}
    -- error is nil

end

result is set to an empty table to indicate that nothing was returned from splash.resume. You can use assert(splash:wait_for_resume(…)) even when JavaScript does not return a value because the empty table signifies success to assert().

Note

Your JavaScript code must contain a main() function. You will get an error if you do not include it. The first argument to this function can have any name you choose, of course. We will call it splash by convention in this documentation.

The next example shows how to return a value from JavaScript to Lua. You can return booleans, numbers, strings, arrays, or objects.

function main(splash)

    local result, error = splash:wait_for_resume([[
        function main(splash) {
            setTimeout(function () {
                splash.resume([1, 2, 'red', 'blue']);
            }, 3000);
        }
    ]])

    -- result is {value={1, 2, 'red', 'blue'}}
    -- error is nil

end

Note

As with splash:evaljs, be wary of returning objects that are too large, such as the $ object in jQuery, which will consume a lot of time and memory to convert to a Lua result.

You can also set additional key/value pairs in JavaScript with the splash.set(key, value) function. Key/value pairs will be included in the result table returned to Lua. The following example demonstrates this.

function main(splash)

    local result, error = splash:wait_for_resume([[
        function main(splash) {
            setTimeout(function () {
                splash.set("foo", "bar");
                splash.resume("ok");
            }, 3000);
        }
    ]])

    -- result is {foo="bar", value="ok"}
    -- error is nil

end

The next example shows an incorrect usage of splash:wait_for_resume(): the JavaScript code does not contain a main() function. result is nil because splash.resume() is never called, and error contains an error message explaining the mistake.

function main(splash)

    local result, error = splash:wait_for_resume([[
        console.log('hello!');
    ]])

    -- result is nil
    -- error is "error: wait_for_resume(): no main() function defined"

end

The next example shows error handling. If splash.error(…) is called instead of splash.resume(), then result will be nil and error will contain the string passed to splash.error(…).

function main(splash)

    local result, error = splash:wait_for_resume([[
        function main(splash) {
            setTimeout(function () {
                splash.error("Goodbye, cruel world!");
            }, 3000);
        }
    ]])

    -- result is nil
    -- error is "error: Goodbye, cruel world!"

end

Your JavaScript code must either call splash.resume() or splash.error() exactly one time. Subsequent calls to either function have no effect, as shown in the next example.

function main(splash)

    local result, error = splash:wait_for_resume([[
        function main(splash) {
            setTimeout(function () {
                splash.resume("ok");
                splash.resume("still ok");
                splash.error("not ok");
            }, 3000);
        }
    ]])

    -- result is {value="ok"}
    -- error is nil

end

The next example shows the effect of the timeout argument. We have set the timeout argument to 1 second, but our JavaScript code will not call splash.resume() for 3 seconds, which guarantees that splash:wait_for_resume() will time out.

When it times out, result will be nil, error will contain a string explaining the timeout, and Lua will continue executing. Calling splash.resume() or splash.error() after a timeout has no effect.

function main(splash)

    local result, error = splash:wait_for_resume([[
        function main(splash) {
            setTimeout(function () {
                splash.resume("Hello, world!");
            }, 3000);
        }
    ]], 1)

    -- result is nil
    -- error is "error: One shot callback timed out while waiting for resume() or error()."

end

Note

The timeout must be >= 0. If the timeout is 0, then splash:wait_for_resume() will never timeout (although Splash’s HTTP timeout still applies).

Note that your JavaScript code is not forceably canceled by a timeout: it may continue to run until Splash shuts down the entire browser context.

See also: splash:runjs, splash:jsfunc, splash:evaljs.

splash:autoload¶

Set JavaScript to load automatically on each page load.

Signature: ok, reason = splash:autoload{source_or_url, source=nil, url=nil}

Parameters:

Returns: ok, reason pair. If ok is nil, error happened and reason contains an error description.

Async: yes, but only when an URL of a remote resource is passed.

splash:autoload allows to execute JavaScript code at each page load. splash:autoload doesn’t execute the passed JavaScript code itself. To execute some code once, after page is loaded use splash:runjs or splash:jsfunc.

splash:autoload can be used to preload utility JavaScript libraries or replace JavaScript objects before a webpage has a chance to do it.

Example:

function main(splash, args)
  splash:autoload([[
    function get_document_title(){
      return document.title;
    }
  ]])
  assert(splash:go(args.url))

  return splash:evaljs("get_document_title()")
end

For the convenience, when a first splash:autoload argument starts with “http://” or “https://” a script from the passed URL is loaded. Example 2 - make sure a remote library is available:

function main(splash, args)
  assert(splash:autoload("https://code.jquery.com/jquery-2.1.3.min.js"))
  assert(splash:go(splash.args.url))
  local version = splash:evaljs("$.fn.jquery")

  return 'JQuery version: ' .. version
end

To disable URL auto-detection use ‘source’ and ‘url’ arguments:

splash:autoload{url="https://code.jquery.com/jquery-2.1.3.min.js"}
splash:autoload{source="window.foo = 'bar';"}

It is a good practice not to rely on auto-detection when the argument is not a constant.

If splash:autoload is called multiple times then all its scripts are executed on page load, in order they were added.

To revert Splash not to execute anything on page load use splash:autoload_reset.

See also: splash:evaljs, splash:runjs, splash:jsfunc, splash:wait_for_resume, splash:autoload_reset.

splash:call_later¶

Arrange for the callback to be called after the given delay seconds.

Signature: timer = splash:call_later(callback, delay)

Parameters:

Returns: a handle which allows to cancel pending timer or reraise exceptions happened in a callback.

Async: no.

Example 1 - take two HTML snapshots, at 1.5s and 2.5s after page loading starts:

function main(splash, args)
  local snapshots = {}
  local timer = splash:call_later(function()
    snapshots["a"] = splash:html()
    splash:wait(1.0)
    snapshots["b"] = splash:html()
  end, 1.5)
  assert(splash:go(args.url))
  splash:wait(3.0)
  timer:reraise()

  return snapshots
end

splash:call_later returns a handle (a timer). To cancel pending task use its timer:cancel() method. If a callback is already started timer:cancel() has no effect.

By default, exceptions raised in splash:call_later callback stop the callback, but don’t stop the main script. To reraise these errors use timer:reraise().

splash:call_later arranges callback to be executed in future; it never runs it immediately, even if delay is 0. When delay is 0 callback is executed no earlier than current function yields to event loop, i.e. no earlier than some of the async functions is called.

splash:http_get¶

Send an HTTP GET request and return a response without loading the result to the browser window.

Signature: response = splash:http_get{url, headers=nil, follow_redirects=true}

Parameters:

Returns: a Response Object.

Async: yes.

Example:

local reply = splash:http_get("http://example.com")

This method doesn’t change the current page contents and URL. To load a webpage to the browser use splash:go.

See also: splash:http_post, Response Object.

splash:http_post¶

Send an HTTP POST request and return a response without loading the result to the browser window.

Signature: response = splash:http_post{url, headers=nil, follow_redirects=true, body=nil}

Parameters:

Returns: a Response Object.

Async: yes.

Example of form submission:

local reply = splash:http_post{url="http://example.com", body="user=Frank&password=hunter2"}
-- reply.body contains raw HTML data (as a binary object)
-- reply.status contains HTTP status code, as a number
-- see Response docs for more info

Example of JSON POST request:

json = require("json")

local reply = splash:http_post{
    url="http://example.com/post",
    body=json.encode({alpha="beta"}),
    headers={["content-type"]="application/json"}
}

This method doesn’t change the current page contents and URL. To load a webpage to the browser use splash:go.

See also: splash:http_get, json, Response Object.

splash:set_content¶

Set the content of the current page and wait until the page loads.

Signature: ok, reason = splash:set_content{data, mime_type="text/html; charset=utf-8", baseurl=""}

Parameters:

Returns: ok, reason pair. If ok is nil then error happened during page load; reason provides an information about error type.

Async: yes.

Example:

function main(splash)
    assert(splash:set_content("<html><body><h1>hello</h1></body></html>"))
    return splash:png()
end
splash:html¶

Return a HTML snapshot of a current page (as a string).

Signature: html = splash:html()

Returns: contents of a current page (as a string).

Async: no.

Example:

-- A simplistic implementation of render.html endpoint
function main(splash)
    splash:set_result_content_type("text/html; charset=utf-8")
    assert(splash:go(splash.args.url))
    return splash:html()
end

Nothing prevents us from taking multiple HTML snapshots. For example, let’s visit first 3 pages on a website, and for each page store initial HTML snapshot and an HTML snapshot after waiting 0.5s:

treat = require("treat")

-- Given an url, this function returns a table
-- with the page screenshoot, it's HTML contents
-- and it's title.
function page_info(splash, url)
  local ok, msg = splash:go(url)
  if not ok then
    return {ok=false, reason=msg}
  end
  local res = {
    html=splash:html(),
    title=splash:evaljs('document.title'),
    image=splash:png(),
    ok=true,
  }
  return res
end

function main(splash, args)
  -- visit first 3 pages of hacker news
  local base = "https://news.ycombinator.com/news?p="
  local result = treat.as_array({})
  for i=1,3 do
    local url =  base .. i
    result[i] = page_info(splash, url)
  end
  return result
end
splash:png¶

Return a width x height screenshot of a current page in PNG format.

Signature: png = splash:png{width=nil, height=nil, render_all=false, scale_method='raster', region=nil}

Parameters:

Returns: PNG screenshot data, as a binary object. When the result is empty nil is returned.

Async: no.

Without arguments splash:png() will take a snapshot of the current viewport.

width parameter sets the width of the resulting image. If the viewport has a different width, the image is scaled up or down to match the specified one. For example, if the viewport is 1024px wide then splash:png{width=100} will return a screenshot of the whole viewport, but the image will be downscaled to 100px width.

height parameter sets the height of the resulting image. If the viewport has a different height, the image is trimmed or extended vertically to match the specified one without resizing the content. The region created by such extension is transparent.

To set the viewport size use splash:set_viewport_size, splash:set_viewport_full or render_all argument. render_all=true is equivalent to running splash:set_viewport_full() just before the rendering and restoring the viewport size afterwards.

To render an arbitrary part of a page use region parameter. It should be a table with {left, top, right, bottom} coordinates. Coordinates are relative to current scroll position. Currently you can’t take anything which is not in a viewport; to make sure part of a page can be rendered call splash:set_viewport_full before using splash:png with region. This may be fixed in future Splash versions.

With region and a bit of JavaScript it is possible to render only a single HTML element. Example:

-- This in an example of how to use lower-level
-- Splash functions to get element screenshot.
--
-- In practice use splash:select("a"):png{pad=32}.


-- this function adds padding around region
function pad(r, pad)
  return {r[1]-pad, r[2]-pad, r[3]+pad, r[4]+pad}
end

function main(splash, args)
  -- this function returns element bounding box
  local get_bbox = splash:jsfunc([[
    function(css) {
      var el = document.querySelector(css);
      var r = el.getBoundingClientRect();
      return [r.left, r.top, r.right, r.bottom];
    }
  ]])

  -- main script
  assert(splash:go(splash.args.url))
  assert(splash:wait(0.5))

  -- don't crop image by a viewport
  splash:set_viewport_full()

  -- let's get a screenshot of a first <a>
  -- element on a page, with extra 32px around it
  local region = pad(get_bbox("a"), 32)
  return splash:png{region=region}
end

An easier way is to use element:png instead:

splash:select('#my-element'):png()

scale_method parameter must be either 'raster' or 'vector'. When scale_method='raster', the image is resized per-pixel. When scale_method='vector', the image is resized per-element during rendering. Vector scaling is more performant and produces sharper images, however it may cause rendering artifacts, so use it with caution.

The result of splash:png is a binary object, so you can return it directly from “main” function and it will be sent as a binary image data with a proper Content-Type header:

-- A simplistic implementation of render.png
-- endpoint.
function main(splash, args)
  assert(splash:go(args.url))

  return splash:png{
    width=args.width,
    height=args.height
  }
end

If the result of splash:png() is returned as a table value, it is encoded to base64 to make it possible to embed in JSON and build a data:uri on a client (magic!):

function main(splash)
    assert(splash:go(splash.args.url))
    return {png=splash:png()}
end

When an image is empty splash:png returns nil. If you want Splash to raise an error in these cases use assert:

function main(splash)
    assert(splash:go(splash.args.url))
    local png = assert(splash:png())
    return {png=png}
end

See also: splash:jpeg, Binary Objects, splash:set_viewport_size, splash:set_viewport_full, element:jpeg, element:png.

splash:jpeg¶

Return a width x height screenshot of a current page in JPEG format.

Signature: jpeg = splash:jpeg{width=nil, height=nil, render_all=false, scale_method='raster', quality=75, region=nil}

Parameters:

Returns: JPEG screenshot data, as a binary object. When the image is empty nil is returned.

Async: no.

Without arguments splash:jpeg() will take a snapshot of the current viewport.

width parameter sets the width of the resulting image. If the viewport has a different width, the image is scaled up or down to match the specified one. For example, if the viewport is 1024px wide then splash:jpeg{width=100} will return a screenshot of the whole viewport, but the image will be downscaled to 100px width.

height parameter sets the height of the resulting image. If the viewport has a different height, the image is trimmed or extended vertically to match the specified one without resizing the content. The region created by such extension is white.

To set the viewport size use splash:set_viewport_size, splash:set_viewport_full or render_all argument. render_all=true is equivalent to running splash:set_viewport_full() just before the rendering and restoring the viewport size afterwards.

To render an arbitrary part of a page use region parameter. It should be a table with {left, top, right, bottom} coordinates. Coordinates are relative to current scroll position. Currently you can’t take anything which is not in a viewport; to make sure part of a page can be rendered call splash:set_viewport_full before using splash:jpeg with region. This may be fixed in future Splash versions.

With some JavaScript it is possible to render only a single HTML element using region parameter. See an example in splash:png docs. An alternative is to use element:jpeg.

scale_method parameter must be either 'raster' or 'vector'. When scale_method='raster', the image is resized per-pixel. When scale_method='vector', the image is resized per-element during rendering. Vector scaling is more performant and produces sharper images, however it may cause rendering artifacts, so use it with caution.

quality parameter must be an integer in range from 0 to 100. Values above 95 should be avoided; quality=100 disables portions of the JPEG compression algorithm, and results in large files with hardly any gain in image quality.

The result of splash:jpeg is a binary object, so you can return it directly from “main” function and it will be sent as a binary image data with a proper Content-Type header:

-- A simplistic implementation of render.jpeg endpoint
function main(splash, args)
    assert(splash:go(args.url))
    return splash:jpeg{
       width=args.width,
       height=args.height
    }
end

If the result of splash:jpeg() is returned as a table value, it is encoded to base64 to make it possible to embed in JSON and build a data:uri on a client:

function main(splash)
    assert(splash:go(splash.args.url))
    return {jpeg=splash:jpeg()}
end

When an image is empty splash:jpeg returns nil. If you want Splash to raise an error in these cases use assert:

function main(splash)
    assert(splash:go(splash.args.url))
    local jpeg = assert(splash:jpeg())
    return {jpeg=jpeg}
end

See also: splash:png, Binary Objects, splash:set_viewport_size, splash:set_viewport_full, element:jpeg, element:png.

Note that splash:jpeg() is often 1.5..2x faster than splash:png().

splash:har¶

Signature: har = splash:har{reset=false}

Parameters:

Returns: information about pages loaded, events happened, network requests sent and responses received in HAR format.

Async: no.

Use splash:har to get information about network requests and other Splash activity.

If your script returns the result of splash:har() in a top-level "har" key then Splash UI will give you a nice diagram with network information (similar to “Network” tabs in Firefox or Chrome developer tools):

function main(splash)
    assert(splash:go(splash.args.url))
    return {har=splash:har()}
end

By default, when several requests are made (e.g. splash:go is called multiple times), HAR data is accumulated and combined into a single object (logs are still grouped by page).

If you want only updated information use reset parameter: it drops all existing logs and start recording from scratch:

function main(splash, args)
    assert(splash:go(args.url1))
    local har1 = splash:har{reset=true}
    assert(splash:go(args.url2))
    local har2 = splash:har()
    return {har1=har1, har2=har2}
end

By default, request and response contents are not included in HAR data. To enable request contents, use splash.request_body_enabled option. To enable response contents, use splash.response_body_enabled option or request:enable_response_body method.

See also: splash:har_reset, splash:on_response, splash.request_body_enabled, splash.response_body_enabled, request:enable_response_body.

splash:har_reset¶

Signature: splash:har_reset()

Returns: nil.

Async: no.

Drops all internally stored HAR records. It is similar to splash:har{reset=true}, but doesn’t return anything.

See also: splash:har.

splash:history¶

Signature: entries = splash:history()

Returns: information about requests/responses for the pages loaded, in HAR entries format.

Async: no.

splash:history doesn’t return information about related resources like images, scripts, stylesheets or AJAX requests. If you need this information use splash:har or splash:on_response.

Let’s get a JSON array with HTTP headers of the response we’re displaying:

function main(splash)
    assert(splash:go(splash.args.url))
    local entries = splash:history()
    -- #entries means "entries length"; arrays in Lua start from 1
    local last_entry = entries[#entries]
    return {
       headers = last_entry.response.headers
    }
end

See also: splash:har, splash:on_response.

splash:url¶

Signature: url = splash:url()

Returns: the current URL.

Async: no.

splash:get_cookies¶

Signature: cookies = splash:get_cookies()

Returns: CookieJar contents - an array with all cookies available for the script. The result is returned in HAR cookies format.

Async: no.

Example result:

[
    {
        "name": "TestCookie",
        "value": "Cookie Value",
        "path": "/",
        "domain": "www.example.com",
        "expires": "2016-07-24T19:20:30+02:00",
        "httpOnly": false,
        "secure": false,
    }
]
splash:add_cookie¶

Add a cookie.

Signature: cookies = splash:add_cookie{name, value, path=nil, domain=nil, expires=nil, httpOnly=nil, secure=nil}

Async: no.

Example:

function main(splash)
    splash:add_cookie{"sessionid", "237465ghgfsd", "/", domain="http://example.com"}
    splash:go("http://example.com/")
    return splash:html()
end
splash:init_cookies¶

Replace all current cookies with the passed cookies.

Signature: splash:init_cookies(cookies)

Parameters:

Returns: nil.

Async: no.

Example 1 - save and restore cookies:

local cookies = splash:get_cookies()
-- ... do something ...
splash:init_cookies(cookies)  -- restore cookies

Example 2 - initialize cookies manually:

splash:init_cookies({
    {name="baz", value="egg"},
    {name="spam", value="egg", domain="example.com"},
    {
        name="foo",
        value="bar",
        path="/",
        domain="localhost",
        expires="2016-07-24T19:20:30+02:00",
        secure=true,
        httpOnly=true,
    }
})

-- do something
assert(splash:go("http://example.com"))
splash:clear_cookies¶

Clear all cookies.

Signature: n_removed = splash:clear_cookies()

Returns: a number of cookies deleted.

Async: no.

To delete only specific cookies use splash:delete_cookies.

splash:delete_cookies¶

Delete matching cookies.

Signature: n_removed = splash:delete_cookies{name=nil, url=nil}

Parameters:

Returns: a number of cookies deleted.

Async: no.

This function does nothing when both name and url are nil. To remove all cookies use splash:clear_cookies method.

splash:lock_navigation¶

Lock navigation.

Signature: splash:lock_navigation()

Async: no.

After calling this method the navigation away from the current page is no longer permitted - the page is locked to the current URL.

splash:unlock_navigation¶

Unlock navigation.

Signature: splash:unlock_navigation()

Async: no.

After calling this method the navigation away from the page becomes permitted. Note that the pending navigation requests suppressed by splash:lock_navigation won’t be reissued.

splash:set_result_status_code¶

Set HTTP status code of a result returned to a client.

Signature: splash:set_result_status_code(code)

Parameters:

Returns: nil.

Async: no.

Use this function to signal errors or other conditions to splash client using HTTP status codes.

Example:

function main(splash)
    local ok, reason = splash:go("http://www.example.com")
    if reason == "http500" then
        splash:set_result_status_code(503)
        splash:set_result_header("Retry-After", 10)
        return ''
    end
    return splash:png()
end

Be careful with this function: some proxies can be configured to process responses differently based on their status codes. See e.g. nginx proxy_next_upstream option.

In case of unhandled Lua errors HTTP status code is set to 400 regardless of the value set with splash:set_result_status_code.

See also: splash:set_result_content_type, splash:set_result_header.

splash:set_result_content_type¶

Set Content-Type of a result returned to a client.

Signature: splash:set_result_content_type(content_type)

Parameters:

Returns: nil.

Async: no.

If a table is returned by “main” function then splash:set_result_content_type has no effect: Content-Type of the result is set to application/json.

This function does not set Content-Type header for requests initiated by splash:go; this function is for setting Content-Type header of a result.

Example:

function main(splash)
    splash:set_result_content_type("text/xml")
    return [[
       <?xml version="1.0" encoding="UTF-8"?>
       <note>
           <to>Tove</to>
           <from>Jani</from>
           <heading>Reminder</heading>
           <body>Don't forget me this weekend!</body>
       </note>
    ]]
end

See also:

splash:get_viewport_size¶

Get the browser viewport size.

Signature: width, height = splash:get_viewport_size()

Returns: two numbers: width and height of the viewport in pixels.

Async: no.

splash:set_viewport_size¶

Set the browser viewport size.

Signature: splash:set_viewport_size(width, height)

Parameters:

Returns: nil.

Async: no.

This will change the size of the visible area and subsequent rendering commands, e.g., splash:png, will produce an image with the specified size.

splash:png uses the viewport size.

Example:

function main(splash)
    splash:set_viewport_size(1980, 1020)
    assert(splash:go("http://example.com"))
    return {png=splash:png()}
end

Note

This will relayout all document elements and affect geometry variables, such as window.innerWidth and window.innerHeight. However window.onresize event callback will only be invoked during the next asynchronous operation and splash:png is notably synchronous, so if you have resized a page and want it to react accordingly before taking the screenshot, use splash:wait.

splash:set_viewport_full¶

Resize browser viewport to fit the whole page.

Signature: width, height = splash:set_viewport_full()

Returns: two numbers: width and height the viewport is set to, in pixels.

Async: no.

splash:set_viewport_full should be called only after page is loaded, and some time passed after that (use splash:wait). This is an unfortunate restriction, but it seems that this is the only way to make automatic resizing work reliably.

See splash:set_viewport_size for a note about interaction with JS.

splash:png uses the viewport size.

Example:

function main(splash)
    assert(splash:go("http://example.com"))
    assert(splash:wait(0.5))
    splash:set_viewport_full()
    return {png=splash:png()}
end
splash:set_user_agent¶

Overwrite the User-Agent header for all further requests.

Signature: splash:set_user_agent(value)

Parameters:

Returns: nil.

Async: no.

splash:get_perf_stats¶

Return performance-related statistics.

Signature: stats = splash:get_perf_stats()

Returns: a table that can be useful for performance analysis.

Async: no.

As of now, this table contains:

splash:on_request¶

Register a function to be called before each HTTP request.

Signature: splash:on_request(callback)

Parameters:

Returns: nil.

Async: no.

splash:on_request callback receives a single request argument (a Request Object).

To get information about a request use request attributes; to change or drop the request before sending use request methods;

A callback passed to splash:on_request can’t call Splash async methods like splash:wait or splash:go.

Example 1 - log all URLs requested using request.url attribute:

treat = require("treat")

function main(splash, args)
  local urls = {}
  splash:on_request(function(request)
    table.insert(urls, request.url)
  end)

  assert(splash:go(splash.args.url))
  return treat.as_array(urls)
end

Example 2 - to log full request information use request.info attribute; don’t store request objects directly:

treat = require("treat")
function main(splash)
    local entries = treat.as_array({})
    splash:on_request(function(request)
        table.insert(entries, request.info)
    end)
    assert(splash:go(splash.args.url))
    return entries
end

Example 3 - drop all requests to resources containing “.css” in their URLs (see request:abort):

splash:on_request(function(request)
    if string.find(request.url, ".css") ~= nil then
        request.abort()
    end
end)

Example 4 - replace a resource (see request:set_url):

splash:on_request(function(request)
    if request.url == 'http://example.com/script.js' then
        request:set_url('http://mydomain.com/myscript.js')
    end
end)

Example 5 - set a custom proxy server, with credentials passed in an HTTP request to Splash (see request:set_proxy):

splash:on_request(function(request)
    request:set_proxy{
        host = "0.0.0.0",
        port = 8990,
        username = splash.args.username,
        password = splash.args.password,
    }
end)

Example 6 - discard requests which take longer than 5 seconds to complete, but allow up to 15 seconds for the first request (see request:set_timeout):

local first = true
splash.resource_timeout = 5
splash:on_request(function(request)
    if first then
        request:set_timeout(15.0)
        first = false
    end
end)

See also: splash:on_response, splash:on_response_headers, splash:on_request_reset, treat, Request Object.

splash:on_request_reset¶

Remove all callbacks registered by splash:on_request.

Signature: splash:on_request_reset()

Returns: nil

Async: no.

splash:on_response_reset¶

Remove all callbacks registered by splash:on_response.

Signature: splash:on_response_reset()

Returns: nil

Async: no.

splash:get_version¶

Get Splash major and minor version.

Signature: version_info = splash:get_version()

Returns: A table with version information.

Async: no.

As of now, this table contains:

Example:

function main(splash)
     local version = splash:get_version()
     if version.major < 2 and version.minor < 8 then
         error("Splash 1.8 or newer required")
     end
 end
splash:mouse_click¶

Trigger mouse click event in web page.

Signature: splash:mouse_click(x, y)

Parameters:

Returns: nil

Async: no.

Coordinates for mouse events must be relative to viewport.

If you want to click on element an easy way is to use splash:select with element:mouse_click:

local button = splash:select('button')
button:mouse_click()

You also can implement it using splash:mouse_click; use JavaScript getClientRects to get coordinates of html element:

-- Get button element dimensions with javascript and perform mouse click.
function main(splash)
    assert(splash:go(splash.args.url))
    local get_dimensions = splash:jsfunc([[
        function () {
            var rect = document.getElementById('button').getClientRects()[0];
            return {"x": rect.left, "y": rect.top}
        }
    ]])
    splash:set_viewport_full()
    splash:wait(0.1)
    local dimensions = get_dimensions()
    -- FIXME: button must be inside a viewport
    splash:mouse_click(dimensions.x, dimensions.y)

    -- Wait split second to allow event to propagate.
    splash:wait(0.1)
    return splash:html()
end

Unlike element:mouse_click, splash:mouse_click is not async. Mouse events are not propagated immediately, to see consequences of click reflected in page source you must call splash:wait if you use splash:mouse_click.

Element on which action is performed must be inside viewport (must be visible to the user). If element is outside viewport and user needs to scroll to see it, you must either scroll to the element (using JavaScript, splash.scroll_position or e.g. element:scrollIntoViewIfNeeded()) or set viewport to full with splash:set_viewport_full.

Under the hood splash:mouse_click performs splash:mouse_press followed by splash:mouse_release.

At the moment only left click is supported.

See also: element:mouse_click, splash:mouse_press, splash:mouse_release, splash:mouse_hover, splash.scroll_position.

splash:mouse_hover¶

Trigger mouse hover (JavaScript mouseover) event in web page.

Signature: splash:mouse_hover(x, y)

Parameters:

Returns: nil

Async: no.

See notes about mouse events in splash:mouse_click.

See also: element:mouse_hover.

splash:mouse_press¶

Trigger mouse press event in web page.

Signature: splash:mouse_press(x, y)

Parameters:

Returns: nil

Async: no.

See notes about mouse events in splash:mouse_click.

splash:mouse_release¶

Trigger mouse release event in web page.

Signature: splash:mouse_release(x, y)

Parameters:

Returns: nil

Async: no.

See notes about mouse events in splash:mouse_click.

splash:with_timeout¶

Run the function with the allowed timeout

Signature: ok, result = splash:with_timeout(func, timeout)

Parameters:

Returns: ok, result pair. If ok is not true then error happened during the function call or the timeout expired; result provides an information about error type. If result is equal to timeout then the specified timeout period elapsed. Otherwise, if ok is true then result contains the result of the executed function. If your function returns several values, they will be assigned to the next variables to result.

Async: yes.

Example 1:

function main(splash, args)
  local ok, result = splash:with_timeout(function()
    -- try commenting out splash:wait(3)
    splash:wait(3)
    assert(splash:go(args.url))
  end, 2)

  if not ok then
    if result == "timeout_over" then
      return "Cannot navigate to the url within 2 seconds"
    else
      return result
    end
  end
  return "Navigated to the url within 2 seconds"
end

Example 2 - the function returns several values

function main(splash)
    local ok, result1, result2, result3 = splash:with_timeout(function()
        splash:wait(0.5)
        return 1, 2, 3
    end, 1)

    return result1, result2, result3
end

Note that if the specified timeout period elapsed Splash will try to interrupt the running function. However, Splash scripts are executed in cooperative multitasking manner and because of that sometimes Splash won’t be able to stop your running function upon timeout expiration. In two words, cooperative multitasking means that the managing program (in our example, it is Splash scripting engine) won’t stop the running function if it doesn’t ask for that. In Splash scripting the running function can be interrupted only if some async operation was called. On the contrary, non of the sync operations can be interrupted.

Note

Splash scripts are executing in cooperative multitasking manner. You should be careful while running sync functions.

Let’s see the difference in examples.

Example 3:

function main(splash)
    local ok, result = splash:with_timeout(function()
        splash:go(splash.args.url) -- during this operation the current function can be stopped
        splash:evaljs(long_js_operation) -- during JS function evaluation the function cannot be stopped
        local png = splash:png() -- sync operation and during it the function cannot be stopped
        return png
    end, 0.1)

    return result
end
splash:send_keys¶

Send keyboard events to page context.

Signature: splash:send_keys(keys)

Parameters

Returns: nil

Async: no.

Key sequences are specified by using a small subset of emacs edmacro syntax:

Following table shows some examples of macros and what they would generate on an input:

Macro Result Hello World HelloWorld Hello <Space> World Hello World < S p a c e > <Space> Hello <Home> <Delete> ello Hello <Backspace> Hell

Key events are not propagated immediately until event loop regains control, thus splash:wait must be called to reflect the events.

See also: element:send_keys, splash:send_text.

splash:send_text¶

Send text as input to page context, literally, character by character.

Signature: splash:send_text(text)

Parameters:

Returns: nil

Async: no.

Key events are not propagated immediately until event loop regains control, thus splash:wait must be called to reflect the events.

This function in conjuction with splash:send_keys covers most needs on keyboard input, such as filling in forms and submitting them.

Example 1: focus first input, fill in a form and submit

function main(splash)
    assert(splash:go(splash.args.url))
    assert(splash:wait(0.5))
    splash:send_keys("<Tab>")
    splash:send_text("zero cool")
    splash:send_keys("<Tab>")
    splash:send_text("hunter2")
    splash:send_keys("<Return>")
    -- note how this could be translated to
    -- splash:send_keys("<Tab> zero <Space> cool <Tab> hunter2 <Return>")
    assert(splash:wait(0))
    -- ...
end

Example 2: focus inputs with javascript or splash:mouse_click

We can’t always assume that a <Tab> will focus the input we want or an <Enter> will submit a form. Selecting an input can either be accomplished by focusing it or by clicking it. Submitting a form can also be done by firing a submit event on the form, or simply by clicking on the submit button.

The following example will focus an input, fill in a form and click on the submit button using splash:mouse_click. It assumes there are two arguments passed to splash, username and password.

function main(splash, args)
    function focus(sel)
        splash:select(sel):focus()
    end

    assert(splash:go(args.url))
    assert(splash:wait(0.5))
    focus('input[name=username]')
    splash:send_text(args.username)
    assert(splash:wait(0))
    focus('input[name=password]')
    splash:send_text(args.password)
    splash:select('input[type=submit]'):mouse_click()
    assert(splash:wait(0))
    -- Usually, wait for the submit request to finish
    -- ...
end

See also: element:send_text, splash:send_keys.

splash:select¶

Select the first HTML element from DOM of the current web page that matches the specified CSS selector.

Signature: element = splash:select(selector)

Parameters:

Returns: an Element object.

Async: no.

Using splash:select you can get the element that matches your specified CSS selector like using document.querySelector in the browser. The returned element is an Element Object which has many useful methods and almost all methods and attributes that element has in JavaScript.

If the element cannot be found using the specified selector nil will be returned. If your selector is not a valid CSS selector an error will be raised.

Example 1: select an element which has element class and return class names off all the siblings of the specified element.

local treat = require('treat')

function main(splash)
    assert(splash:go(splash.args.url))
    assert(splash:wait(0.5))

    local el = splash:select('.element')
    local seen = {}
    local classNames = {}

    while el do
      local classList = el.node.classList
      if classList then
        for _, v in ipairs(classList) do
          if (not seen[v]) then
            classNames[#classNames + 1] = v
            seen[v] = true
          end
        end
      end

      el = el.node.nextSibling
    end

    return treat.as_array(classNames)
end

Example 2: assert that the returned element exists

function main(splash)
    -- ...
    local el = assert(splash:select('.element'))
    -- ...
end
splash:select_all¶

Select the list of HTML elements from DOM of the current web page that match the specified CSS selector.

Signature: elements = splash:select_all(selector)

Parameters:

Returns: a list of Element objects.

Async: no.

This method differs from splash:select by returning the all elements in a table that match the specified selector.

If no elements can be found using the specified selector {} is returned. If the selector is not a valid CSS selector an error is raised.

Example: select all <img /> elements and get their src attributes

local treat = require('treat')

function main(splash)
    assert(splash:go(splash.args.url))
    assert(splash:wait(0.5))

    local imgs = splash:select_all('img')
    local srcs = {}

    for _, img in ipairs(imgs) do
      srcs[#srcs+1] = img.node.attributes.src
    end

    return treat.as_array(srcs)
end
splash:on_navigation_locked¶

Register a function to be called before a request is discarded when navigation is locked.

Signature: splash:on_navigation_locked(callback)

Parameters:

Returns: nil.

Async: no.

splash:on_navigation_locked callback receives a single request argument (a Request Object).

To get information about a request use request attributes;

A callback passed to splash:on_navigation_locked can’t call Splash async methods like splash:wait or splash:go.

Example 1 - log all URLs discarded using request.url attribute:

treat = require("treat")

function main(splash, args)
  local urls = {}
  splash:on_navigation_locked(function(request)
    table.insert(urls, request.url)
  end)

  assert(splash:go(splash.args.url))
  splash:lock_navigation()
  splash:select("a"):mouse_click()
  return treat.as_array(urls)
end
splash:on_navigation_locked_reset¶

Remove all callbacks registered by splash:on_navigation_locked.

Signature: splash:on_navigation_locked_reset()

Returns: nil

Async: no.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4