Rust浏览器自动化插件库re_redap_browser的使用,高效实现网页抓取与自动化测试
Rust浏览器自动化插件库re_redap_browser的使用,高效实现网页抓取与自动化测试
re_redap_browser是rerun系列crate的一部分,用于实现浏览器自动化功能。
安装
在项目目录中运行以下Cargo命令:
cargo add re_redap_browser
或在Cargo.toml中添加以下行:
re_redap_browser = "0.24.0"
基本示例
以下是使用re_redap_browser进行网页抓取和自动化测试的完整示例:
use re_redap_browser::Browser;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 创建浏览器实例
let browser = Browser::new().await?;
// 导航到目标网页
browser.goto("https://example.com").await?;
// 获取网页标题
let title = browser.title().await?;
println!("网页标题: {}", title);
// 查找元素并点击
if let Ok(button) = browser.find_element("button#submit").await {
button.click().await?;
println!("已点击提交按钮");
}
// 获取元素文本内容
if let Ok(element) = browser.find_element("div.content").await {
let text = element.text().await?;
println!("内容文本: {}", text);
}
// 截图保存
browser.screenshot("screenshot.png").await?;
println!("已保存截图");
// 执行JavaScript
let result: String = browser.execute_script("return document.readyState").await?;
println!("文档状态: {}", result);
Ok(())
}
高级自动化测试示例
use re_redap_browser::Browser;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 初始化浏览器,可配置选项
let browser = Browser::builder()
.headless(true) // 无头模式
.user_agent("MyCustomAgent/1.0")
.build()
.await?;
// 测试登录流程
browser.goto("https://example.com/login").await?;
// 填写表单
browser.find_element("input#username").await?.send_keys("testuser").await?;
browser.find_element("input#password").await?.send_keys("password123").await?;
// 提交表单
browser.find_element("button#login").await?.click().await?;
// 等待导航完成并验证
browser.wait_for_navigation().await?;
assert!(browser.current_url().await?.contains("dashboard"));
// 验证登录成功
let welcome_msg = browser.find_element("div.welcome").await?.text().await?;
assert!(welcome_msg.contains("Welcome, testuser"));
// 测试注销功能
browser.find_element("a#logout").await?.click().await?;
browser.wait_for_navigation().await?;
assert!(browser.current_url().await?.contains("login"));
Ok(())
}
网页抓取示例
use re_redap_browser::Browser;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let browser = Browser::new().await?;
browser.goto("https://news.ycombinator.com").await?;
// 获取所有新闻条目
let stories = browser.find_elements("tr.athing").await?;
for story in stories {
// 获取标题和链接
let title_element = story.find_element("span.titleline > a").await?;
let title = title_element.text().await?;
let url = title_element.attribute("href").await?;
// 获取分数
let score = story.find_element("span.score").await?.text().await?;
println!("标题: {}", title);
println!("链接: {}", url.unwrap_or_default());
println!("分数: {}", score);
println!("------");
}
Ok(())
}
完整示例代码
以下是一个结合了网页抓取和自动化测试功能的完整示例:
use re_redap_browser::Browser;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 初始化浏览器配置
let browser = Browser::builder()
.headless(false) // 可视化模式
.build()
.await?;
// 测试电商网站功能
println!("开始测试电商网站...");
browser.goto("https://demo.ecommerce.com").await?;
// 验证首页加载
let title = browser.title().await?;
assert!(title.contains("E-Commerce Demo"));
println!("首页加载成功: {}", title);
// 搜索商品
browser.find_element("input#search").await?.send_keys("Rust编程书").await?;
browser.find_element("button#search-btn").await?.click().await?;
browser.wait_for_navigation().await?;
// 获取搜索结果
let products = browser.find_elements("div.product-item").await?;
println!("找到 {} 个商品", products.len());
// 点击第一个商品
if !products.is_empty() {
products[0].find_element("a").await?.click().await?;
browser.wait_for_navigation().await?;
// 添加到购物车
browser.find_element("button#add-to-cart").await?.click().await?;
println!("商品已添加到购物车");
// 返回首页
browser.find_element("a#home").await?.click().await?;
browser.wait_for_navigation().await?;
}
// 截图保存测试结果
browser.screenshot("ecommerce_test.png").await?;
println!("测试完成,截图已保存");
Ok(())
}
许可证: MIT OR Apache-2.0
1 回复
Rust浏览器自动化插件库re_redap_browser使用指南
概述
re_redap_browser是一个Rust语言的浏览器自动化库,专门设计用于高效实现网页抓取和自动化测试任务。它提供了简洁的API来控制和操作浏览器,支持主流浏览器如Chrome、Firefox等。
主要特性
- 支持无头(Headless)和有头浏览器模式
- 提供DOM元素定位和操作功能
- 支持表单填写和提交
- 支持JavaScript执行
- 支持页面截图和PDF生成
- 支持网络请求拦截和修改
- 轻量级且高性能
安装方法
在Cargo.toml中添加依赖:
[dependencies]
re_redap_browser = "0.3"
基本使用方法
1. 启动浏览器实例
use re_redap_browser::{Browser, BrowserOptions};
async fn start_browser() -> Result<(), Box<dyn std::error::Error>> {
let options = BrowserOptions::default()
.headless(true) // 无头模式
.disable_images(true); // 禁用图片加载提升性能
let browser = Browser::launch(options).await?;
Ok(())
}
2. 打开页面并获取内容
use re_redap_browser::{Browser, Page};
async fn scrape_page() -> Result<(), Box<dyn std::error::Error>> {
let browser = Browser::launch_default().await?;
let page = browser.new_page().await?;
// 导航到目标URL
page.goto("https://example.com").await?;
// 等待特定元素出现
page.wait_for_selector("#main-content").await?;
// 获取页面HTML
let html = page.content().await?;
println!("Page HTML: {}", html);
Ok(())
}
3. 表单操作示例
async fn fill_form() -> Result<(), Box<dyn std::error::Error>> {
let browser = Browser::launch_default().await?;
let page = browser.new_page().await?;
page.goto("https://example.com/login").await?;
// 填写表单
page.type_("#username", "my_username").await?;
page.type_("#password", "secure_password").await?;
// 点击提交按钮
page.click("#submit-btn").await?;
// 等待导航完成
page.wait_for_navigation().await?;
Ok(())
}
4. 截图功能
async fn take_screenshot() -> Result<(), Box<dyn std::error::Error>> {
let browser = Browser::launch_default().await?;
let page = browser.new_page().await?;
page.goto("https://example.com").await?;
// 全屏截图
page.screenshot("screenshot.png", None).await?;
// 元素截图
page.screenshot_element("#featured-section", "element.png").await?;
Ok(())
}
5. 执行JavaScript
async fn execute_js() -> Result<(), Box<dyn std::error::Error>> {
let browser = Browser::launch_default().await?;
let page = browser.new_page().await?;
page.goto("https://example.com").await?;
// 执行JavaScript并获取返回值
let result: String = page.evaluate("document.title").await?;
println!("Page title: {}", result);
// 执行复杂JavaScript
let sum: i32 = page.evaluate("1 + 2 + 3").await?;
println!("Sum: {}", sum);
Ok(())
}
高级用法
网络请求拦截
use re_redap_browser::{Request, Response};
async fn intercept_requests() -> Result<(), Box<dyn std::error::Error>> {
let browser = Browser::launch_default().await?;
let page = browser.new_page().await?;
// 启用请求拦截
page.en极request_interception(true).await?;
// 设置请求拦截回调
page.on_request(move |req: Request| {
// 阻止所有图片请求
if req.resource_type() == "image" {
req.abort();
} else {
req.continue_();
}
}).await;
page.goto("https://example.com").await?;
Ok(())
}
并行处理多个页面
use futures::future::join_all;
async fn multiple_pages() -> Result<(), Box<dyn std::error::Error>> {
let browser = Browser::launch_default().await?;
let urls = vec![
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3",
];
let tasks = urls.into_iter().map(|url| {
let browser = browser.clone();
async move {
let page = browser.new_page().await?;
page.goto(url).await?;
let title = page.evaluate("document.title").await?;
Ok::<_, Box<dyn std::error::Error>>(title)
}
});
let results = join_all(tasks).await;
for result in results {
println!("Page title: {}", result?);
}
Ok(())
}
最佳实践
- 资源管理: 确保在使用完毕后关闭页面和浏览器实例
- 错误处理: 妥善处理网络超时和元素查找失败等情况
- 性能优化: 禁用不必要的资源加载(如图片、CSS)以提升速度
- 随机延迟: 在爬取时添加随机延迟避免被封锁
- 用户代理轮换: 定期更换User-Agent模拟不同设备
常见问题解决
- 元素查找失败: 确保使用正确的选择器,并添加足够的等待时间
- 内存泄漏: 定期重启浏览器实例,特别是在长时间运行的爬虫中
- 反爬机制: 考虑使用代理IP和更人性化的操作模式
完整示例Demo
下面是一个完整的网页抓取示例,结合了等待元素、获取内容和截图功能:
use re_redap_browser::{Browser, BrowserOptions};
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 配置浏览器选项
let options = BrowserOptions::default()
.headless(true)
.disable_images(true)
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
// 启动浏览器
let browser = Browser::launch(options).await?;
// 创建新页面
let page = browser.new_page().await?;
// 导航到目标网站
page.goto("https://example.com").await?;
// 等待主要内容加载
page.wait_for_selector("#main-content").await?;
// 随机延迟防止被屏蔽
sleep(Duration::from_secs_f64(rand::random::<f64>() * 2.0)).await;
// 获取页面标题
let title: String = page.evaluate("document.title").await?;
println!("页面标题: {}", title);
// 获取特定元素文本
let content: String = page.evaluate(
"document.querySelector('#main-content').textContent"
).await?;
println!("主要内容: {}", content);
// 截图保存
page.screenshot("example_screenshot.png", None).await?;
// 关闭页面
page.close().await?;
// 关闭浏览器
browser.close().await?;
Ok(())
}
这个示例展示了:
- 浏览器配置和启动
- 页面导航和等待元素
- 添加随机延迟避免被检测
- 获取页面内容和执行JavaScript
- 截图功能
- 资源清理(关闭页面和浏览器)
您可以根据实际需求修改和扩展这个基础示例。