Rust浏览器自动化库chromiumoxide的使用,通过Rust控制Chromium实现高效网页爬取与自动化测试
Rust浏览器自动化库chromiumoxide的使用,通过Rust控制Chromium实现高效网页爬取与自动化测试
chromiumoxide 提供了一个高级的异步API来控制Chrome或Chromium浏览器,通过DevTools协议进行通信。它支持所有类型的Chrome DevTools协议,可以启动无头(headless)或有头的Chromium实例,也可以连接到正在运行的实例。
使用方法
以下是使用chromiumoxide进行网页自动化操作的完整示例:
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?;
// 创建一个新任务来持续轮询处理程序
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?;
// 查找搜索框,输入内容并按下Enter键
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进行网页爬取和自动化测试:
use futures::StreamExt;
use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::page::PrintToPdfParams;
#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 配置浏览器选项 - 无头模式,窗口大小等
let config = BrowserConfig::builder()
.with_head() // 显示UI界面
.with_window_size(1280, 720)
.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.screenshot(chromiumoxide::page::ScreenshotParams::builder()
.with_full_page(true)
.build()?)
.await?
.save("example_screenshot.png")
.await?;
// 生成PDF
let pdf_params = PrintToPdfParams::builder()
.with_landscape(false)
.with_display_header_footer(false)
.build()?;
let pdf_data = page.pdf(pdf_params).await?;
async_std::fs::write("example.pdf", pdf_data).await?;
// 表单自动化
page.find_element("input[name='username']")
.await?
.type_str("testuser")
.await?;
page.find_element("input[name='password']")
.await?
.type_str("password123")
.await?;
page.find_element("button[type='submit']")
.await?
.click()
.await?;
// 等待特定元素出现
let success_element = page.wait_for_element(".success-message").await?;
let success_text = success_element.inner_text().await?;
println!("Success message: {}", success_text);
// 获取页面所有链接
let links = page.find_elements("a").await?;
for link in links {
let href = link.attribute("href").await?;
let text = link.inner_text().await?;
println!("Link: {} - {}", text, href.unwrap_or_default());
}
// 关闭浏览器
browser.close().await?;
handle.await;
Ok(())
}
添加到项目
chromiumoxide支持async-std和tokio运行时。默认配置使用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"}
常见问题
Q: 一个新的chromium实例被启动但随后超时。
A: 检查你的chromium语言设置是否为英语。chromiumoxide尝试从chromium进程输出中解析调试端口,这仅限于英语。
chromiumoxide提供了强大的浏览器自动化功能,非常适合网页爬取和自动化测试场景。通过其丰富的API,开发者可以轻松实现复杂的浏览器交互操作。
Rust浏览器自动化库chromiumoxide使用指南
概述
chromiumoxide是一个基于Rust的浏览器自动化库,它允许开发者通过Rust代码控制Chromium浏览器,实现网页爬取和自动化测试功能。这个库提供了与Chrome DevTools Protocol的交互能力,类似于Python中的Pyppeteer或Selenium。
主要特性
- 完全异步支持(基于tokio)
- 支持页面导航、表单填写、点击等操作
- 支持JavaScript执行
- 支持网络请求拦截和修改
- 支持截图和PDF生成
- 轻量级且性能高效
安装方法
在Cargo.toml中添加依赖:
[dependencies]
chromiumoxide = "0.7"
tokio = { version = "1.0", features = ["full"] }
基本使用方法
1. 启动浏览器实例
use chromiumoxide::browser::{Browser, BrowserConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 配置浏览器
let (browser, mut handler) = Browser::launch(
BrowserConfig::builder()
.with_head() // 无头模式
.build()?
).await?;
// 处理浏览器事件的任务
let handle = tokio::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?;
// 其他操作...
// 关闭浏览器
browser.close().await?;
handle.await?;
Ok(())
}
2. 页面导航与内容获取
// 导航到页面
page.goto("https://www.rust-lang.org").await?;
// 获取页面标题
let title = page.evaluate("document.title").await?;
println!("页面标题: {:?}", title);
// 获取页面HTML内容
let content = page.content().await?;
println!("页面内容: {}", content);
3. 元素交互操作
// 点击元素
page.find_element("button#submit").await?.click().await?;
// 填写表单
page.find_element("input#username")
.await?
.type_str("rust_user")
.await?;
// 选择下拉框选项
page.find_element("select#country")
.await?
.select_by_value("US")
.await?;
4. 截图和PDF生成
// 截取整个页面
page.screenshot()
.full_page(true)
.save("screenshot.png")
.await?;
// 生成PDF
page.pdf()
.landscape(false)
.scale(1.0)
.save("output.pdf")
.await?;
5. 网络请求拦截
use chromiumoxide::handler::network::RequestPattern;
// 设置请求拦截
let pattern = RequestPattern::builder()
.url_str("*.png")
.resource_type("Image")
.build();
page.set_request_interception(&[pattern]).await?;
// 处理被拦截的请求
while let Some(req) = page.next_request().await {
if req.url().ends_with(".png") {
req.abort().await?;
} else {
req.continue_request().await?;
}
}
高级用法
并行控制多个页面
let pages = browser.new_pages(3).await?; // 创建3个新页面
for (i, page) in pages.into_iter().enumerate() {
page.goto(&format!("https://example.com/page{}", i)).await?;
// 其他操作...
}
执行复杂JavaScript
let result = page.evaluate(
r#"
(function() {
const elements = document.querySelectorAll('.item');
return Array.from(elements).map(el => el.textContent);
})()
"#
).await?;
println!("提取的内容: {:?}", result);
完整示例Demo
下面是一个完整的chromiumoxide使用示例,展示了从启动浏览器到抓取页面数据的完整流程:
use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::page::Page;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 启动浏览器实例(无头模式)
let (browser, mut handler) = Browser::launch(
BrowserConfig::builder()
.with_head()
.build()?
).await?;
// 处理浏览器事件的任务
let handle = tokio::task::spawn(async move {
while let Some(h) = handler.next().await {
if h.is_err() {
break;
}
}
});
// 2. 创建新页面并导航
let page = browser.new_page("https://www.rust-lang.org").await?;
page.wait_for_navigation().await?;
// 3. 获取页面信息
let title = page.evaluate("document.title").await?;
println!("页面标题: {:?}", title);
// 4. 截图保存
page.screenshot()
.full_page(true)
.save("rust_lang.png")
.await?;
// 5. 执行复杂JavaScript提取数据
let items = page.evaluate(
r#"
(function() {
const items = [];
document.querySelectorAll('a').forEach(link => {
items.push({
text: link.innerText,
href: link.href
});
});
return items;
})()
"#
).await?;
println!("提取到的链接: {:?}", items);
// 6. 关闭浏览器
browser.close().await?;
handle.await?;
Ok(())
}
注意事项
- 首次运行会自动下载Chromium浏览器,可能需要较长时间
- 无头模式适合生产环境,调试时可去掉
with_head()
配置 - 确保正确处理异步任务和错误
- 复杂的页面可能需要添加等待逻辑
chromiumoxide为Rust开发者提供了强大的浏览器自动化能力,特别适合需要高性能爬取或测试的场景。相比其他语言的类似工具,它能提供更好的内存安全性和并发性能。