Rust浏览器自动化库chromiumoxide_pdl的使用,支持Chromium协议解析与自动化测试
Rust浏览器自动化库chromiumoxide_pdl的使用,支持Chromium协议解析与自动化测试
chromiumoxide 提供了一个高级异步API来控制 Chrome 或 Chromium 通过 DevTools 协议。它支持所有 Chrome DevTools 协议类型,可以启动无头(headless)或完整(非无头)的 Chrome/Chromium 实例,或连接到已运行的实例。
使用示例
use futures::StreamExt;
use chromiumoxide::browser::{Browser, BrowserConfig};
#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个带有UI的浏览器实例 (默认是无头模式)
let (mut browser, mut handler) =
Browser::launch(BrowserConfig::builder().with_head().build()?).await?;
// 创建一个持续处理handler的新任务
let handle = async_std::task::spawn(async move {
while let Some(h) = handler.next().await {
if h.is_err() {
break;
}
}
});
// 创建一个新页面并导航到URL
let page = browser.new_page("https://en.wikipedia.org").await?;
// 查找搜索框,输入搜索内容并回车
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(())
}
完整示例代码
下面是一个更完整的示例,展示了如何使用chromiumoxide_pdl进行Chromium协议解析和自动化测试:
use futures::StreamExt;
use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::page::Page;
use chromiumoxide::types::PrintToPdfParams;
#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 配置浏览器选项
let config = BrowserConfig::builder()
.with_head() // 显示UI
.with_timeout(std::time::Duration::from_secs(30))
.build()?;
// 启动浏览器
let (mut browser, mut handler) = Browser::launch(config).await?;
// 处理浏览器事件
let handle = async_std::task::spawn(async move {
while let Some(h) = handler.next().await {
if h.is_err() {
break;
}
}
});
// 创建新页面
let page = browser.new_page("https://example.com").await?;
// 等待页面加载完成
page.wait_for_navigation().await?;
// 截图
let screenshot = page.screenshot().await?;
std::fs::write("screenshot.png", screenshot)?;
// 生成PDF
let pdf_params = PrintToPdfParams::builder()
.landscape(false)
.display_header_footer(false)
.print_background(true)
.build();
let pdf = page.pdf(pdf_params).await?;
std::fs::write("page.pdf", pdf)?;
// 执行自定义协议命令
let title = page.title().await?;
println!("Page title: {}", title);
// 关闭浏览器
browser.close().await?;
handle.await;
Ok(())
}
如何添加到项目
chromiumoxide支持async-std和tokio运行时。默认使用async-std。
使用async-std运行时:
chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", branch = "main"}
使用tokio运行时:
chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", features = ["tokio-runtime"], default-features = false, branch = "main"}
代码生成
chromiumoxide_pdl包含一个PDL解析器和一个将解析的PDL文件转换为Rust代码的生成器。chromiumoxide_cdp的唯一目的是在构建过程中调用生成器并包含生成的输出。
已知问题
- 当手动关闭对实验性类型的支持时(export CDP_NO_EXPERIMENTAL=true),生成的Rust文件无法编译。
故障排除
Q: 新的chromium实例被启动但随后超时。 A: 检查你的chromium语言设置是否为英语。chromiumoxide尝试从chromium进程输出中解析调试端口,这仅限于英语。
Rust浏览器自动化库chromiumoxide_pdl使用指南
chromiumoxide_pdl
是一个Rust库,用于Chromium协议解析和浏览器自动化测试。它提供了与Chromium浏览器交互的能力,支持自动化操作和协议级别的控制。
主要特性
- Chromium DevTools Protocol (CDP) 解析
- 浏览器自动化控制
- 页面导航与操作
- 元素查找与交互
- 网络请求拦截与修改
- JavaScript执行
安装
在Cargo.toml中添加依赖:
[dependencies]
chromiumoxide_pdl = "0.5"
tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
完整示例代码
下面是一个完整的浏览器自动化示例,结合了内容中提供的各个功能点:
use chromiumoxide_pdl::{
browser::{Browser, BrowserConfig},
cdp::{
browser_protocol::network::{RequestPattern, EventRequestWillBeSent},
browser_protocol::performance::{EnableParams, Metric}
}
};
use futures::{StreamExt, FutureExt};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 配置并启动浏览器
let config = BrowserConfig::builder()
.headless(true) // 无头模式
.timeout(Duration::from_secs(30)) // 设置超时时间
.build()?;
let (mut browser, mut handler) = Browser::launch(config).await?;
// 处理浏览器事件的异步任务
let browser_task = tokio::task::spawn(async move {
while let Some(h) = handler.next().await {
if h.is_err() {
break;
}
}
});
// 2. 创建新页面并导航
let page = browser.new_page("about:blank").await?;
// 3. 设置网络请求拦截
let patterns = vec![
RequestPattern {
url_pattern: Some("*.png".to_string()),
resource_type: None,
interception_stage: None,
}
];
page.set_request_interception(patterns).await?;
// 启动拦截请求处理任务
let mut events = page.event_listener::<EventRequestWillBeSent>().await?;
let intercept_task = tokio::spawn(async move {
while let Some(event) = events.next().await {
let request = event.request;
println!("拦截到请求: {}", request.url);
// 这里可以添加请求处理逻辑
}
});
// 导航到目标网站
page.goto("https://www.rust-lang.org").await?;
page.wait_for_navigation().await?;
// 4. 页面元素操作
// 查找并点击"Learn"链接
if let Some(button) = page.find_element("a[href='/learn']").await? {
button.click().await?;
page.wait_for_navigation().await?;
}
// 在搜索框中输入并搜索
if let Some(search) = page.find_element("input[type='search']").await? {
search.type_str("Rust book").await?;
search.press_key("Enter").await?;
page.wait_for_navigation().await?;
}
// 5. 执行JavaScript
// 获取页面标题
let title: String = page.evaluate("document.title").await?;
println!("当前页面标题: {}", title);
// 修改页面背景色
page.evaluate("document.body.style.backgroundColor = 'lightblue'").await?;
// 6. 性能监控
// 启用性能指标收集
page.execute(EnableParams::default()).await?;
// 获取性能指标
let metrics: Vec<Metric> = page.evaluate("window.performance.getEntries()").await?;
println!("性能指标:");
for metric in metrics {
println!("{}: {}", metric.name, metric.value);
}
// 7. 自定义协议解析示例
use chromiumoxide_pdl::pdl::Parser;
let pdl = r#"
domain MyDomain
version 1.0
type MyType extends object
properties
string name
integer id
"#;
let parser = Parser::new();
let protocol = parser.parse(pdl)?;
println!("解析的自定义协议类型: {:?}", protocol.types);
// 清理工作
intercept_task.abort();
browser.close().await?;
browser_task.await?;
Ok(())
}
代码说明
-
浏览器启动:配置无头浏览器并启动,设置超时时间防止长时间等待。
-
页面导航:创建新页面并导航到目标URL,等待页面完全加载。
-
网络拦截:设置拦截规则,捕获所有PNG图片请求并打印URL。
-
元素操作:
- 查找并点击页面上的特定元素
- 在输入框中输入文本并模拟回车键
-
JavaScript执行:
- 获取页面标题
- 修改页面样式
-
性能监控:收集并打印页面性能指标。
-
自定义协议解析:演示如何使用PDL解析自定义协议。
注意事项
- 确保系统中已安装Chromium或Chrome浏览器
- 适当添加等待时间处理页面加载延迟
- 网络拦截会增加请求处理开销
- 资源使用完毕后要正确关闭和清理
这个完整示例展示了chromiumoxide_pdl库的主要功能,可以根据实际需求进行修改和扩展。