度贴吧网 Go 语言写的基于 DevTools Protocol 的工具 Rod 介绍
2024-07-02 03:07:12发布 浏览50次 信息编号:77321
友情提醒:凡是以各种理由向你收取费用,均有骗子嫌疑,请提高警惕,不要轻易支付。
度贴吧网 Go 语言写的基于 DevTools Protocol 的工具 Rod 介绍
在日常开发中,我们可能经常会遇到以下场景:需要借助一些自动化的手段来帮助我们进行测试;在获取某些网页数据时,目标网页的数据是动态的,无法使用传统的数据获取方式进行有效抓取;我们需要时不时地抓取某个网页并保存为截图,用于竞品监控分析;诸如此类的场景在过去可能我们很难实现,或者现有的工具或多或少都存在一些不足。今天,我将介绍一款基于 Go 语言的工具,叫做 Rod。
Rod 的地址:
Rod 是什么?
Rod 是一个直接基于 的高级驱动程序,专为 Web 自动化和抓取而设计。Rod 还向用户暴露了一些低级接口,以便在缺少某些功能时,用户可以直接调用这些接口向浏览器发送控制请求。
罗德能做什么?
由于是基于该协议的,所以可以实现大部分基本的功能,比如浏览器页面控制、窗口控制、事件监听、根据选择器获取网页元素、模拟鼠标移动与点击、页面事件监听与触发、网页注入脚本、样式表、网页内容修改、网页内容获取、脚本执行、获取设置、页面截图、重用、页面监控等功能。
Rod 是如何工作的?
Rod 被调用后会尝试连接,如果找不到,会根据不同系统在一些默认路径中尝试寻找本地浏览器,找到就打开,如果找不到就尝试下载一个再重新启动。
然后 Rod 使用 JSON-RPC 与浏览器进行交互,从而实现对浏览器的控制。当需要控制某个具体页面时,Rod 会在页面中注入一个 js 辅助脚本,Rod 通过这个脚本来获取并控制页面内容。
其他类似工具存在什么问题?
由于需要复杂的 DSL 类任务来处理主要逻辑,因此很难理解代码,也很难在问题发生时追踪问题。它也很难处理,不支持影子 DOM,并且在程序崩溃时会留下僵尸进程。
由于基于,功能相对较少,比如不能处理封闭式影子 DOM、不能将网页另存为 PDF、不支持性能工具、依赖浏览器驱动导致难以使用和维护等。虽然号称支持跨浏览器,但实际上在很多浏览器上都存在或多或少的问题。
需要处理复杂的/async/await问题,但是在进行自动化测试的时候,人们希望先同步获取状态,再进行后续操作,这对于QA来说不是很友好。
关闭影子 DOM 的限制非常严格,并且对于跨域来说不太安全。
案例一:定期截取网页截图
前面提到过,有时候我们需要长期关注竞争对手的网页,需要定期保存快照进行分析,这时候就可以使用 rod 来方便的满足这个需求。
这里我写了一个小方法,每3秒请求一次gocn网站(为了测试,实际环境可以调整为半天,一天等),然后在页面加载完成后,对整个页面进行截图并以截图时间为文件名保存在本地。
import ( "github.com/go-rod/rod" "strconv" "time")func monitorGocn() { // 创建一个浏览器的实例 browser := rod.New().Connect() url := "https://gocn.vip" // 指定要获取的网页 page := browser.Page(url) // 指定窗口大小,避免截图时截不完整 page.Window(0, 0, 1024, 768) // 指定截图间隔时间,我这里是测试,就设置了3秒 interval := time.Duration(3) * time.Second for { select { case nowTimestamp := time.Now().Unix() nowTimestampStr := strconv.Itoa(int(nowTimestamp)) // 重定向页面,后面的参数无实意,只是为了确保页面刷新 page.Navigate(url + "/?__t__=" + nowTimestampStr) // 等待页面加载完成 wait := page.WaitRequestIdle() wait() file := "screenshot/" + nowTimestampStr + ".jpg" // 整个页面截图并保存 page.ScreenshotFullPage(file) } }}
截图结果:
截图效果如下:
案例 2:自动登录百度论坛
本案例主要以百度贴吧自动登录为例演示自动化操作,我们复用用户的登录信息,设置一些需要登录的贴吧的数组,每天自动打开各个贴吧首页,点击登录按钮即可登录。
通过检查登录按钮,很容易获得相应的元素选择器。
然后我们编写代码:
import ( "github.com/go-rod/rod" "github.com/go-rod/rod/lib/launcher" "time")func signInBa() { // 以NewUserMode形式启动,这样可以复用会话信息 // 当然你也可以以普通模式启动,自己调用程序登录 url := launcher.NewUserMode().Launch() browser := rod.New().ControlURL(url).Connect() // 先打开某度贴吧首页,方便复用 page := browser.Page("https://tieba.example.com/") // 设定窗口大小 page.Window(0, 0, 1024, 768) // 等待页面加载完成 wait := page.WaitRequestIdle() wait() // 这里是需要签到的贴吧的名称 kws := []string{"php", "java", "javascript"} for _, kw := range kws { // 组装贴吧地址 url := "https://tieba.example.com/f?kw=" + kw // 前往某个贴吧首页 page.Navigate(url) wait = page.WaitRequestIdle() wait() // 点击签到按钮 page.Element(".j_signbtn").Click() // 休息10秒再继续 time.Sleep(time.Duration(10) * time.Second) }}
执行之后可以看到如下效果:
上面两个案例只是沧海一粟,充分利用 Rod 所能实现的功能远不止这些。它还支持在 中启动浏览器,也就是说你可以在服务器上使用 Rod 的所有功能,把写好的程序扔到服务器上等着它按时执行就可以了。它还支持监控,可以自行处理错误并返回。
总之,使用好Rod可以大大提高你的工作效率,还可以帮助你完成各种定制的自动化功能和高级数据捕获需求。
提醒:请联系我时一定说明是从奢侈品修复培训上看到的!