2个稳定版本

1.0.2 2022年12月17日
1.0.1 2022年11月26日
1.0.0 2022年10月30日

#125 in WebSocket

39 每月下载量
webscrape 中使用

MIT 许可证

1MB
23K SLoC

无头Chrome

Build Status Crate API Discord channel

通过DevTools协议控制无头Chrome或Chromium的高级API。它是Chrome DevTools团队维护的Node库Puppeteer的Rust等效版本。

它并非与Puppeteer完全兼容,但提供了足够的功能来满足大多数浏览器测试/网络爬虫用例,并且还有一些“高级”功能,例如

快速开始

use std::error::Error;

use headless_chrome::Browser;
use headless_chrome::protocol::cdp::Page;

fn browse_wikipedia() -> Result<(), Box<dyn Error>> {
    let browser = Browser::default()?;

    let tab = browser.wait_for_initial_tab()?;

    /// Navigate to wikipedia
    tab.navigate_to("https://www.wikipedia.org")?;

    /// Wait for network/javascript/dom to make the search-box available
    /// and click it.
    tab.wait_for_element("input#searchInput")?.click()?;

    /// Type in a query and press `Enter`
    tab.type_str("WebKit")?.press_key("Enter")?;

    /// We should end up on the WebKit-page once navigated
    let elem = tab.wait_for_element("#firstHeading")?;
    assert!(tab.get_url().ends_with("WebKit"));

    /// Take a screenshot of the entire browser window
    let _jpeg_data = tab.capture_screenshot(
        Page::CaptureScreenshotFormatOption::Jpeg,
        None,
        None,
        true)?;

    /// Take a screenshot of just the WebKit-Infobox
    let _png_data = tab
        .wait_for_element("#mw-content-text > div > table.infobox.vevent")?
        .capture_screenshot(Page::CaptureScreenshotFormatOption::Png)?;

    // Run JavaScript in the page
    let remote_object = elem.call_js_fn(r#"
        function getIdTwice () {
            // `this` is always the element that you called `call_js_fn` on
            const id = this.id;
            return id + id;
        }
    "#, vec![], false)?;
    match remote_object.value {
        Some(returned_string) => {
            dbg!(&returned_string);
            assert_eq!(returned_string, "firstHeadingfirstHeading".to_string());
        }
        _ => unreachable!()
    };

    Ok(())
}

自动获取chrome二进制文件

[dependencies]
headless_chrome = {git = "https://github.com/atroche/rust-headless-chrome", features = ["fetch"]}

对于更完整的示例,请参阅tests/simple.rsexamples

在运行示例之前。请确保在Cargo.toml中将failure crate添加到您的cargo项目依赖项中

它不能做什么?

Chrome DevTools Protocol非常大。目前,Puppeteer支持的功能比我们多得多。一些缺失的功能包括

  • 处理框架
  • 处理文件选择器/选择器交互
  • 触摸屏触摸
  • 模拟不同的网络条件(DevTools可以更改延迟、吞吐量、离线状态、“连接类型”)
  • 查看网络请求的时间信息
  • 读取SSL证书
  • 重新播放XHRs
  • HTTP基本认证
  • 检查EventSource(即服务器发送事件或SSEs)
  • WebSocket检查

如果您有兴趣添加这些功能之一,但想了解如何开始,请创建一个issue或通过以下邮箱地址联系我:alistair@sunburnt.country

  • fantoccini使用WebDriver,因此它也适用于Chrome以外的浏览器。它也是异步的,基于Tokio,与headless_chrome不同,后者有一个同步API,仅使用普通的线程实现。Fantoccini也存在更久,并且经过更多的实战检验。它不支持Chrome DevTools特定的功能,如JS Coverage。

测试

为了调试输出,在运行cargo test之前设置这些环境变量。

RUST_BACKTRACE=1 RUST_LOG=headless_chrome=trace

版本号

从v0.2.0版本开始,我们尝试严格遵循SemVar。

故障排除

如果您收到与超时相关的错误,您可能需要在内核中或作为setuid沙盒启用沙盒。Puppeteer有一些关于如何做的信息这里

默认情况下,headless_chrome将下载兼容的Chrome版本到XDG_DATA_HOME(或在Windows/Mac上的等效位置)。此行为可以关闭,您可以通过在您的Cargo.toml中禁用默认功能来使用系统版本的Chrome(假设您已经安装了Chrome)。

[dependencies.headless_chrome]
default-features = false

贡献

欢迎提交pull请求和issue,即使它们只是经验报告。如果您发现任何令人沮丧或困惑的地方,请告诉我!

依赖

~12–25MB
~413K SLoC