度贴吧网 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可以大大提高你的工作效率,还可以帮助你完成各种定制的自动化功能和高级数据捕获需求。

提醒:请联系我时一定说明是从奢侈品修复培训上看到的!