【Rust】thirtyfour의 Webdriver 자동 업데이트 및 실행

Table of Contents
Rust의 thirtyfour는 Selenium이나 Playwright처럼 Webdriver를 사용하여 브라우저를 자동으로 제어하여 web 앱의 테스트를 하거나, 스크래핑 등을 통해 값의 검증을 할 수 있는 도구입니다. thirtyfour에 의한 자동화를 실현하기 위해서는 일반적인 절차로 해당 브라우저의 버전에 맞춰 미리 Webdriver를 설치하고, 그 실행 절차가 있습니다. 브라우저의 버전 업그레이드 시마다 Webdriver의 업데이트도 필요하기 때문에, 은근히 번거로운 절차이며 비기술자에게 프로그램을 전달하는 경우 Webdriver 업데이트 관련 트러블이 자주 발생합니다.
Python 등 다른 언어의 Selenium에서는 SeleniumManager라는 실행 파일이 포함되어 있으며, 이를 사용하여 Webdriver의 자동 업데이트를 수행하고, 업데이트된 Webdriver의 path를 Selenium에 제공하여 자동으로 Webdriver를 시작하는 메커니즘이 있습니다. 이 중 Webdriver의 자동 업데이트를 담당하는 SeleniumManager가 Rust 언어로 작성되어 GitHub에서 관리되므로, Rust 언어 그대로 SeleniumManager를 재사용하여 thirtyfour를 위한 Webdriver의 자동 업데이트가 가능합니다.
그 절차와 샘플 코드를 기록합니다.
코드
이 코드에서 중요한 점은 SeleniumManager를 재사용하여 번거로움 없이 WebDriver의 업데이트를 Rust 언어 그대로 실현하는 것입니다. SeleniumManager의 소스 코드는 GitHub에서 확인할 수 있습니다.
cargo.toml
cargo.toml에는 selenium-manager를 GitHub에서 불러오도록 작성합니다. 그 밖에 thirtyfour나 tokio 등 필요한 크레이트를 도입합니다.
[package]
name = ""
version = "0.1.0"
edition = "2021"
[dependencies]
selenium-manager = { git = "https://github.com/SeleniumHQ/selenium", branch = "trunk" }
thirtyfour = "0.31.0"
tokio = "1.38.0"
main.rs
use selenium_manager::get_manager_by_browser;
use std::error::Error;
use std::process::Command;
use std::time::Duration;
use thirtyfour::prelude::*;
struct ChromeDriverManager {
driver_path: String,
}
impl ChromeDriverManager {
async fn new(browser: String) -> Result<Self, Box<dyn Error + Send + Sync>> {
let driver_path = tokio::task::spawn_blocking(move || {
let mut manager = get_manager_by_browser(browser)?;
Ok::<_, Box<dyn Error + Send + Sync>>(manager.setup()?.to_str().ok_or("Invalid path")?.to_string())
})
.await??;
Ok(Self { driver_path })
}
fn start(&self) -> Result<(), Box<dyn Error + Send + Sync>> {
Command::new(&self.driver_path)
.spawn()
.map_err(|e| format!("ChromeDriver의起動に失敗しました: {}", e))?;
std::thread::sleep(Duration::from_secs(2)); // 起動待機
Ok(())
}
}
async fn run_browser_session() -> Result<(), Box<dyn Error + Send + Sync>> {
let driver = WebDriver::new("http://localhost:9515", DesiredCapabilities::chrome()).await?;
driver.goto("https://www.example.com").await?;
println!("Page title: {}", driver.title().await?);
driver.quit().await?;
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let chromedriver_manager = ChromeDriverManager::new("chrome".to_string()).await?;
chromedriver_manager.start()?;
run_browser_session().await
}
解説
cargo.toml에 dependencies를 추가한 후, use selenium_manager::get_manager_by_browser;
를 작성하여 SeleniumManager를 재사용할 수 있습니다. get_manager_by_browser에 브라우저 이름을 입력하면 해당 브라우저의 Webdriver를 자동으로 설치하고, 그 파일 경로의 문자열을 얻을 수 있습니다. 그 후, start를 실행하여 명령어를 통해 해당 버전의 Webdriver를 자동으로 실행할 수 있습니다.
그 후의 절차는 일반적인 thirtyfour의 코드 작성과 동일합니다. 샘플 코드로서 example.com에 접근하여 그 페이지 제목을 출력하는 처리만 되어 있습니다.
まとめ
브라우저의 버전 업그레이드와 함께 Webdriver의 업데이트도 일반적으로 필요하지만, SeleniumManager의 이용으로 이 절차를 생략할 수 있습니다. Docker를 사용하여 컨테이너 상에서 Selenium을 동작시키는 방법도 있지만, 이 방법이라면 Docker도 불필요하며 비기술자에게 더 쉽게 전달할 수 있는 테스트나 스크래핑·크롤링 등의 자동화를 실현할 수 있습니다. SeleniumManager를 재사용하는 것만으로 개발자에게도 손쉬운 방법이므로,ぜひお試しください。