分享一个用于自动化和爬虫的库

2020-09-21 09:23:51 +08:00
 ysmood

项目地址: https://github.com/go-rod/rod

感谢大家的反馈优化了不少 API,因为之前的帖子已经过时了,所以在这里重新发下帖子。近期主要优化了异常处理。基本覆盖了 puppeteer 的主要功能,且支持更多便利的高级功能,比如等待 ajax,复杂代理,文件下载等。

这个库的主要原理就是利用浏览器的 devtools 可编程接口来操控浏览器。日常你可以用它自动化一些重复的页面任务,相比油猴子有更多的高级功能和 golang 强大的生态。工作上可以用它辅助集成化测试减少人力消耗。开发上可以用它简化一些传统爬虫需要费很多时间逆向工程的场景。

欢迎对自动化有兴趣的朋友加入到项目中来,这是我们的聊天室: https://discord.gg/PAaMGJw

可以通过示例文件大致了解 rod 的一些基本用法: https://github.com/go-rod/rod/blob/master/examples_test.go

下图是 rod,puppeteer 和 chromedp 实现相同输出的代码对比:

更多对比请移步: https://github.com/go-rod/rod/tree/master/lib/examples/compare-chromedp

关于 Must 前缀: https://github.com/go-rod/rod/blob/03b1d54362f72599d3bfa465aee6b48c9c51599b/examples_test.go#L137-L186

12946 次点击
所在节点    分享创造
61 条回复
ysmood
2020-09-21 09:25:33 +08:00
比如这两天我将用 rod 每小时自动置顶一次这个帖子,示例项目: https://github.com/go-rod/v2ex-example
playniuniu
2020-09-21 09:38:29 +08:00
非常好用 支持一下
playniuniu
2020-09-21 09:40:13 +08:00
另外 能否出一个详细一点的文档 直接看 example test 代码还是有点费劲
supermoonie
2020-09-21 09:40:39 +08:00
需要多少线程支持一个 tab ?
ysmood
2020-09-21 09:51:47 +08:00
@supermoonie 好奇你这个问题的出发点是啥。要在单核 CPU 上跑吗?理论上用了 Go 一个线程就够了 (green threads),不是很清楚该如何回答你这个问题。
ysmood
2020-09-21 09:56:33 +08:00
@playniuniu 确实,目前还没有教程,感觉最近可能会花点时间出点教程,比如录个视频或者直播之类的会对我来说负担小点,写文章比较费精力。确实是想收集大家的想法才发帖子的,有什么具体想学的吗?
playniuniu
2020-09-21 10:00:09 +08:00
如果有可能 能否找几个网站 从最简单的 解析网页表单 ,操作鼠标点击 到比较复杂的过滑动验证码 eval js 等等 还有比较骚操作的 hijack 请求 bypass 这些 每一个能给个案例并讲解一下 rod 实现原理就好了
ysmood
2020-09-21 10:11:02 +08:00
@playniuniu 好的,应该问题不大。还会讲解下如何利用 rod 调试复杂场景,这个也是很多人常常问的,这种就很难写文章,不录屏幕太麻烦解释了。
xwhxbg
2020-09-21 10:12:44 +08:00
是我火星了还是 promise 不支持 timeout 了? Pupeteer 不支持 abort slow operation,这个不是用 promise timeout 封装一下就行了么?
ysmood
2020-09-21 10:22:54 +08:00
@xwhxbg 我是自己实现过 promise 库的,研究了很多 nodejs 底层工作原理的: https://github.com/ysmood/yaku

这说法其实是对比于 Go 的 context 特性来说的。大致就是指,比如一个 operation 要耗费一个小时,如果你用 nodejs 的 promise,实际上这个 operation 相关的资源还是驻留在内存的,并没有 abort 释放,只有到一个小时后才会释放。比如 cdp 的通信,由于是基于 websocket 的 frame,puppeteer 并没有实现原子级别的 abort 。你要想释放单个请求只能断开整个 websocket 链接,而 rod 这种就不用了,可以很原子的操作细节。
ysmood
2020-09-21 10:25:01 +08:00
xwhxbg
2020-09-21 10:44:50 +08:00
@ysmood 呃,大家不都是用 bluebird 家的 promise 实现么? ES6 的确实没法 cancel,但是 bluebird 家的有 abort 之类的
daizige
2020-09-21 10:46:48 +08:00
持续关注中 感觉会很有意思
ysmood
2020-09-21 10:54:12 +08:00
@xwhxbg 所以你得去了解 abort 的底层机制,bluebird 也没法解决我说的问题,它的 abort 对我来说都是虚假的 abort,实际还是在后台消耗资源。
ysmood
2020-09-21 11:11:41 +08:00
@xwhxbg golang 贯穿整个系统底层的 context 概念是 nodejs 是很难比拟的: https://golang.org/pkg/context/

Promise 设计之初压根就没好好考虑 abort,草案直接放弃了这个方向的探寻。

写 puppeteer 大量重复的 async await 反复横跳于代码间。有时候写漏了 await 还不容易察觉。我个人觉得严重破坏了用 IDE 自动点点点补全的流畅感。
xwhxbg
2020-09-21 11:13:17 +08:00
@ysmood 我实在是没看懂你说的“底层机制”是什么,如果想要 cancel 请求,es6 就有 abort,如果想要 then 里面直接跳过,立刻回收内存,bluebird 也能实现
xwhxbg
2020-09-21 11:22:48 +08:00
@ysmood context 只是一个 handle 而已啊,贯穿底层是指什么呢? promise 传一个 object 当 handle 也是可以的啊。

golang 的 cancel 就是很正常的一个 handle,文档也说了`A CancelFunc does not wait for the work to stop. `说明即使调用了 cancel 也不能让代码立刻结束

可以描述一下你想要的 cancel 是什么效果吗?
ysmood
2020-09-21 11:26:25 +08:00
@xwhxbg 这个 google 一下类似关键字都可以出结果: https://stackoverflow.com/questions/29478751/cancel-a-vanilla-ecmascript-6-promise-chain

你看这个人说 bluebird 可以,然后评论的人就说的很清楚了:

this definition of canceled is just rejecting the promise. it depends on the definition of "canceled"

This is partially right, but if you have long promise chain, this approach would not work.

我觉挺清楚了啊,各种人都讨论过这个问题。

你说 ”es6 就有 abort“,能给个 ES6 官方的 spec 链接 吗?我好奇啥时候出的
xwhxbg
2020-09-21 11:35:44 +08:00
@ysmood https://stackoverflow.com/questions/31061838/how-do-i-cancel-an-http-fetch-request

我不太理解,即使没有 bluebird,写一个带 handle 的 cancel 也是很容易的事情

```javascript
let handle = { cancel: false};

let result = dosomething(handle).then(handle=>{
if (handle.cancel){
throw("cancel error");
}
});

...

function cancel(){
handle.cancel = true;
}
```
supermoonie
2020-09-21 11:37:55 +08:00
@ysmood 用 java 实现过这个协议,因为没有用异步 io,websocket 发送一个线程,接收一个线程,事件处理也是一个线程池在支持,所以问下 go 实现的话,是不是像 node 那样基于事件处理?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/708906

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX