13个不稳定版本 (6个破坏性更新)

新版本 0.7.0 2024年8月12日
0.6.0 2024年5月28日
0.5.2 2023年9月29日
0.5.1 2023年7月24日
0.1.0 2020年12月13日

#329 in 网页开发

Download history 974/week @ 2024-04-23 878/week @ 2024-04-30 1218/week @ 2024-05-07 1241/week @ 2024-05-14 912/week @ 2024-05-21 1555/week @ 2024-05-28 1566/week @ 2024-06-04 1332/week @ 2024-06-11 1288/week @ 2024-06-18 939/week @ 2024-06-25 1413/week @ 2024-07-02 1426/week @ 2024-07-09 2143/week @ 2024-07-16 1777/week @ 2024-07-23 1624/week @ 2024-07-30 1319/week @ 2024-08-06

7,197 每月下载量
用于 26 个crates (2直接使用)

MIT/Apache

4.5MB
102K SLoC

chromiumoxide

Build Crates.io Documentation

chromiumoxide 提供了一个高级和异步API,用于通过DevTools协议控制Chrome或Chromium。它支持Chrome DevTools协议的所有类型,并可以启动一个无头或全功能(非无头)的Chrome或Chromium实例,或者连接到已运行的实例。

使用方法

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(())
}

当前的API仍缺少一些功能,但Page::execute 函数允许发送所有 chromiumoxide_types::Command 类型(见 生成的代码)。大多数 ElementPage 函数基本上只是简化的命令构造和组合,例如 Page::pdf

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

如果您需要其他功能,Page::execute 函数允许您编写自己的命令包装器。如果您认为缺少有意义的命令,请提交PR。

将chromiumoxide添加到您的项目中

chromiumoxide 包含对 async-stdtokio 运行时的支持。

默认情况下,chromiumoxide 配置为使用 async-std

使用chromiumoxideasync-std运行时

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

要使用 tokio 运行时,请添加 features = ["tokio-runtime"] 并将 default-features = false 设置为禁用默认运行时(async-std

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

这种配置主要是由选择的 websocket 库实现的:[async-tungstenite]

生成的代码

chromiumoxide_pdl 库包含一个 PDL 解析器,它是铬源代码树中一个 Python 脚本 的 Rust 重写,以及一个 Generator,它将解析的 PDL 文件转换为 Rust 代码。chromiumoxide_cdp 库的唯一目的是在其 构建过程 中调用生成器并在编译该库之前 包含生成的输出。这种分离仅仅是因为生成的输出是约 60K 行的 Rust 代码(不包括所有过程宏展开)。因此,请预计编译需要一些时间。生成器可以独立配置和使用,请参阅 chromiumoxide_cdp/build.rs

每个 Chrome PDL 域都放在自己的 Rust 模块中,browser_protocol 页面域的类型在 chromiumoxide_cdp::cdp::browser_protocol::page 中,js_protocol 的运行域在 chromiumoxide_cdp::cdp::js_protocol::runtime 中,依此类推。

vanilla.aslushnikov.com 是一个浏览 pdl 文件中定义的所有类型的绝佳资源。该网站将 pdl 文件中定义的 Command 类型显示为 Methodchromiumoxid 保留 Command 命名法。因此,对于在 pdl 中定义为命令类型的所有内容(在 vanilla.aslushnikov.com 上标记为 Method),chromiumoxide 包含一个命令类型和一个指定的返回类型。对于每个命令都有一个 <命令名称>Params 类型,具有构建器支持(<命令名称>Params::builder())和相应的返回类型:<命令名称> Returns。所有命令都共享 chromiumoxide_types::Command 特质的实现。所有事件都包含在单个枚举(CdpEvent)中

获取器

默认情况下,chromiumoxide 将尝试在运行它的计算机上找到已安装的铬版本。对于某些平台,可以使用 fetcher 自动下载和安装。

由于 Cargo 的一个错误,这些功能目前有些混乱,一旦解决,将进行更改。根据您的运行时和 TLS 配置,您应该启用以下之一

  • _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()?,
}

已知问题

  • chromiumoxide_cdp 中为 PDL 文件生成的 rust 文件,在手动关闭对实验类型支持的情况下无法编译(export CDP_NO_EXPERIMENTAL=true)。这是因为 *.pdl 文件中某些实验性 pdl 类型的使用本身并未标记为实验性。

故障排除

问:正在启动一个新的铬实例,但随后超时。

答:请检查您的铬语言设置是否设置为英语。chromiumoxide 尝试从铬进程输出中解析调试端口,这仅限于英语。

许可证

根据以下之一获得许可

参考文献

依赖关系

~3–5MB
~90K SLoC