Headless Chrome and Rust

Darin Gordon

RustNYC - July 2019

Headless Chrome

  • Released in June 2017
  • Exposes Chrome functionality through an API

- Websockets using DevTools Protocol

  • VERY useful collection of tools

- Command line

Use Cases

  • Screenshots

  • Render PDF

Automated Testing

  • Visual Regression Testing
  • Workflow Testing

Miscellaneous Services

Driving the Browser

  • Scraping

 Headless Chrome Clients

  • Authored by Google
  • Written in NodeJS
  • User-friendly, intuitive API
  • The official reference client

 Headless Chrome Clients

Pyppeteer

rust-headless-chrome

Some languages ported the API really well

(and others did it their own way)

rust-headless-chrome

  • Port of Puppeteer to Rust
  • Project began OSS in early 2019
  • Several features, yet far from feature parity with Puppeteer
  • Generate screenshots and PDFs of pages

unofficial logo

rust-headless-chrome

API in a nutshell

Create a Browser instance

Spawn a Tab off of the Browser

Use Tab to navigate and perform actions

rust-headless-chrome

PDF Generation


    let browser = Browser::connect(chrome_url)?;
    
    let tab = browser.wait_for_initial_tab()?;
    
    let local_pdf = tab
        .navigate_to(&uri)?
        .wait_until_navigated()?
        .print_to_pdf(pdf_options)?;
    
    fs::write("report.pdf", &local_pdf)?;

rust-headless-chrome

Screen Snapshot


    let browser = Browser::default()?;
    let tab = browser.wait_for_initial_tab()?;
    tab.navigate_to("https://www.wikipedia.org")?;
    tab.wait_for_element("input#searchInput")?;
    
    let jpeg_data = tab.capture_screenshot(
                        ScreenshotFormat::JPEG(Some(75)),
                        None,
                        true)?;
    
    fs::write("page.jpg", &jpeg_data)?;

Use Case: PDF Report-Generating Service

A Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.

Gotenberg

  • I didn't need this functionality
  • Web server, headless chrome, and process monitoring all in a single Docker image

1.7GB Docker Image, 1GB+ stripped

Use Case: PDF Report-Generating Service

  • Just renders pdfs from uploaded web files
  • Uses actix-web framework
  • Secured using bearer auth

So... I wrote my own service in Rust!

Use Case: PDF Report-Generating Service

So... I wrote my own service in Rust! (continued)

musl cross-compiled static exec binary:

9.7MB

headless chrome + alpine:

309MB

15.3MB

service binary + alpine:

(headless chrome is the bottleneck)

Use Case: PDF Report-Generating Service

So... I wrote my own service in Rust! (continued)

Would you like to walk through the code together next time?

Until Then..

Questions?

Made with Slides.com