rust实现selenium

selenium是基于webdriver协议的自动化测试工具,当然也能用来做爬虫。

selenium有很多语言版本,但是没有rust版本的,仓库里的是一个rust实现的浏览器和driver下载器。

目前crates.io上的三方实现很久没有更新了,而且缺乏功能,所以选择自己实现。

协议

selenium原理并不稀奇,主要是借助一个driver操作浏览器。selenium使用http和driver通信。所以实际上最核心的功能都在由浏览器厂商实现的driver里,说selenium只是个壳子也不为过。

采用的协议是webdriver

流程

略去driver下载相关,首先需要启动driver,开发过程都是基于firefox和geckodriver。

1
geckodriver --host 127.0.0.1 --port 2983

不同的driver启动参数不同。

我将启动driver流程集成到了代码里,但是由于rust的特性,容易产生孤儿进程,前后改了很多次,依旧不能保证没问题,只能说只要能正常退出程序,不要中途panic,基本就能避免。


之后是创建一个session。可以简单理解一个session就是一个单独的浏览器进程,这里有一些注意事项

  • session不能重复创建,一个driver同时只能有一个session,也就是没法操作多个浏览器实例,只能使用多个driver
  • 必须调用quit。只有调用了quit方法,session才会被销毁,否则除非重启dervier,不然不能再创建session
  • 每个session都是新环境,历史记录插件等即不继承也不遗留,除非设置profile
  • profile会被压缩后用base64传输,所以并非是driver或者浏览器所在设备的某个路径,而是selenium程序来读取压缩的

执行

除了selenium提供的元素操作方法外,最好用的还是执行js代码。

js执行环境为当前网页,实际效果就和在控制台里执行一样。

需要注意同步和异步,同步js直接return即可,异步方法则略有不同

1
let v:String = driver.execute_async_script(r#" let callback = arguments[arguments.length - 1]; setTimeout(()=> callback(100) ,1000);  "#,&[]).unwrap();

js里可以通过arguments获取传入的方法,最后一个值是回调函数,异步方法结束时调用返回执行结果

突破反爬

有的网站防火墙会校验浏览器是否处于webdriver协议控制下,其原理就是此时浏览器会将window.navigator.webdriver设置为true。


目前有两种思路避开

一是 使用chrome的debug方式连接一个已打开的窗口,而非新窗口,但是时不时会出现连不上的情况。

二是 使用低版本(小于68)的firefox,通过设置pref dom.webdriver.enabled=false

三是 options.add_experimental_option('excludeSwitches', ['enable-automation'])

参考资料


rust实现selenium
http://blog.inkroom.cn/2025/07/21/R8BYJ4.html
作者
inkbox
发布于
2025年7月21日
许可协议