• Stars
    star
    522
  • Rank 84,811 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created almost 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Chrome Devtools Protocol rust API

chromiumoxide

Build Crates.io Documentation

chromiumoxide provides a high-level and async API to control Chrome or Chromium over the DevTools Protocol. It comes with support for all types of the Chrome DevTools Protocol and can launch a headless or full (non-headless) Chrome or Chromium instance or connect to an already running instance.

Usage

use futures::StreamExt;

use chromiumoxide::browser::{Browser, BrowserConfig};

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    
   // create a `Browser` that spawns a `chromium` process running with UI (`with_head()`, headless is default) 
   // and the handler that drives the websocket etc.
    let (mut browser, mut handler) =
        Browser::launch(BrowserConfig::builder().with_head().build()?).await?;
    
   // spawn a new task that continuously polls the handler
    let handle = async_std::task::spawn(async move {
        while let Some(h) = handler.next().await {
            if h.is_err() {
                break;
            }
        }
    });
    
   // create a new browser page and navigate to the url
    let page = browser.new_page("https://en.wikipedia.org").await?;
    
   // find the search bar type into the search field and hit `Enter`,
   // this triggers a new navigation to the search result page
   page.find_element("input#searchInput")
           .await?
           .click()
           .await?
           .type_str("Rust programming language")
           .await?
           .press_key("Enter")
           .await?;

   let html = page.wait_for_navigation().await?.content().await?;
   
    browser.close().await?;
    handle.await;
    Ok(())
}

The current API still lacks some functionality, but the Page::execute function allows sending all chromiumoxide_types::Command types (see Generated Code). Most Element and Page functions are basically just simplified command constructions and combinations, like Page::pdf:

pub async fn pdf(&self, params: PrintToPdfParams) -> Result<Vec<u8>> {
     let res = self.execute(params).await?;
     Ok(base64::decode(&res.data)?)
 }

If you need something else, the Page::execute function allows for writing your own command wrappers. PRs are very welcome if you think a meaningful command is missing a designated function.

Add chromiumoxide to your project

chromiumoxide comes with support for the async-std and tokio runtime.

By default chromiumoxide is configured with async-std.

Use chromiumoxide with the async-std runtime:

chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", branch = "main"}

To use the tokio runtime instead add features = ["tokio-runtime"] and set default-features = false to disable the default runtime (async-std):

chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", features = ["tokio-runtime"], default-features = false, branch = "main"}

This configuration is made possible primarily by the websocket crate of choice: async-tungstenite.

Generated Code

The chromiumoxide_pdl crate contains a PDL parser, which is a rust rewrite of a python script in the chromium source tree and a Generator that turns the parsed PDL files into rust code. The chromiumoxide_cdp crate only purpose is to invoke the generator during its build process and include the generated output before compiling the crate itself. This separation is done merely because the generated output is ~60K lines of rust code (not including all the proc macro expansions). So expect the compiling to take some time. The generator can be configured and used independently, see chromiumoxide_cdp/build.rs.

Every chrome pdl domain is put in its own rust module, the types for the page domain of the browser_protocol are in chromiumoxide_cdp::cdp::browser_protocol::page, the runtime domain of the js_protocol in chromiumoxide_cdp::cdp::js_protocol::runtime and so on.

vanilla.aslushnikov.com is a great resource to browse all the types defined in the pdl files. This site displays Command types as defined in the pdl files as Method. chromiumoxid sticks to the Command nomenclature. So for everything that is defined as a command type in the pdl (=marked as Method on vanilla.aslushnikov.com) chromiumoxide contains a type for command and a designated type for the return type. For every command there is a <name of command>Params type with builder support (<name of command>Params::builder()) and its corresponding return type: <name of command>Returns. All commands share an implementation of the chromiumoxide_types::Command trait. All Events are bundled in single enum (CdpEvent)

Fetcher

By default chromiumoxide will try to find an installed version of chromium on the computer it runs on. It is possible to download and install one automatically for some platforms using the fetcher.

Ther features are currently a bit messy due to a Cargo bug and will be changed once it is resolved. Based on your runtime and TLS configuration you should enable one of the following:

  • _fetcher-rustls-async-std
  • _fetcher-rusttls-tokio
  • _fetcher-native-async-std
  • _fetcher-native-tokio
use std::path::Path;

use futures::StreamExt;

use chromiumoxide::browser::{BrowserConfig};
use chromiumoxide::fetcher::{BrowserFetcher, BrowserFetcherOptions};

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let download_path = Path::new("./download");
    async_std::fs::create_dir_all(&download_path).await?;
    let fetcher = BrowserFetcher::new(
        BrowserFetcherOptions::builder()
            .with_path(&download_path)
            .build()?,
    );
    let info = fetcher.fetch().await?;

    let config = BrowserConfig::builder()
        .chrome_executable(info.executable_path)
        .build()?,
}

Known Issues

  • The rust files generated for the PDL files in chromiumoxide_cdp don't compile when support for experimental types is manually turned off (export CDP_NO_EXPERIMENTAL=true). This is because the use of some experimental pdl types in the *.pdl files themselves are not marked as experimental.

Troubleshooting

Q: A new chromium instance is being launched but then times out.

A: Check that your chromium language settings are set to English. chromiumoxide tries to parse the debugging port from the chromium process output and that is limited to english.

License

Licensed under either of these:

References

More Repositories

1

voyager

crawl and scrape web pages in rust
Rust
614
star
2

cargo-memex

compile rust code into memes
Rust
245
star
3

defi-bindings

rust bindings for various defi projects
Rust
63
star
4

diffeq

Basic Ordinary Differential Equation solvers
Rust
49
star
5

extrablatt

Article scraping in rust
Rust
46
star
6

cairo-lang-rs

Rust
38
star
7

libp2p-bittorrent-protocol

Rust Implementation of the BitTorrent protocol for libp2p.
Rust
23
star
8

hyperswarm-dht

rust implementation fo the DHT powering the HyperSwarm stack
Rust
17
star
9

crossref-rs

A rust client for the Crossref-API
Rust
13
star
10

str-distance

String Distances in rust
Rust
13
star
11

hypertrie

Secure, distributed single writer key/value store
Rust
11
star
12

hardhat-anvil

TypeScript
9
star
13

plcopen-xml-xcore

The PlcOpen Xml Standard implemented as Xcore model and with full gradle and maven support
Java
9
star
14

archiveis-rs

A simple rust wrapper for the archive.is capturing service.
Rust
6
star
15

kaggle-rs

unofficial rust bindings for the kaggle api
Rust
6
star
16

aoc2021

Python
4
star
17

nom-sparql

Sparql parser written in rust using nom
Rust
4
star
18

rustika

rust bindings to the Apache Tikaβ„’ REST services
Rust
4
star
19

tia-openness-xcore

Xcore model of the TIA Openness documents.
Java
3
star
20

tokio-interval-repro

Rust
3
star
21

forge-ethers-rs-template

a template for starting an ethers-rs project backed by forge
3
star
22

substrate-exchange-xcmp

Deposit, withdraw and swap (parachain) assets
Rust
2
star
23

rust-plexapi

Rust bindings for the Plex API.
Rust
2
star
24

template

basic rust template
Rust
2
star
25

rust-s7

Rust
2
star
26

plcopen-xml

java parser for the plcopen-xml standard
Java
1
star
27

callgraph-graphml

Java
1
star
28

rust-ads

Implementation of Beckhoff's ADS protocol in pure rust.
Rust
1
star
29

windows-envs

Rust
1
star
30

smolgrad

Rust
1
star