Playwright Logo搞自动化测试或者写爬虫的同学,估计都被Selenium折磨过。那玩意儿配置起来麻烦,驱动版本老是对不上,而且速度还慢。
最近我在GitHub上挖到一个宝,是微软Playwright的Go语言社区版——playwright-go。这玩意儿简直是为Go开发者量身打造的浏览器自动化利器,不用装Python,不用配Node.js,直接用Go就能操控Chromium、Firefox、WebKit三大浏览器。
它到底能干啥
简单说,就是一个用Go写的浏览器遥控器。你可以拿它做:
- 自动化测试:模拟用户点点点,填表单,测你的Web应用
- 网页截图:把整个网页或者某个元素截下来,长截图也没问题
- 爬虫抓数据:对付那些JavaScript渲染的页面,比requests好用多了
- 多浏览器兼容:一份代码,Chrome、Firefox、Safari都能跑
最牛的是它的自动等待机制。以前用Selenium的时候,老是得手动写time.sleep()猜页面啥时候加载完。playwright-go会智能等,元素没出来它就等着,出来了马上操作,稳得很。
安装其实不难,就几步
很多人看到"浏览器自动化"就头大,觉得要装一堆东西。其实 playwright-go 的安装已经挺简化了。
第一步:装好Go环境
这个不用我说吧,确保你电脑上有Go 1.18+版本,GOPATH也设置好。
第二步:下载库
go get -u github.com/playwright-community/playwright-go
第三步:装浏览器驱动(关键!)
这一步很多人会漏掉,然后报错说找不到driver。有两个法子:
法子一:命令行装(推荐)
# 先装命令行工具go install github.com/playwright-community/playwright-go/cmd/playwright@latest# 再装浏览器,--with-deps会把系统依赖也装上playwright install --with-deps
法子二:代码里自动装
你也可以在Go代码里调用playwright.Install(),不过有时候权限不够,某些系统依赖装不上,所以推荐上面的命令行方式。
装完大概会下载200MB左右的东西,包含Chromium、Firefox、WebKit三个浏览器内核。喝杯咖啡等等就好了。
写个Hello World
来,咱们撸个最简单的例子,打开百度截个图:
package mainimport ("log""github.com/playwright-community/playwright-go")funcmain() {// 启动Playwright pw, err := playwright.Run()if err != nil { log.Fatalf("启动失败: %v", err) }defer pw.Stop()// 开Chrome,headless=false能看到窗口 browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{ Headless: playwright.Bool(false), })if err != nil { log.Fatalf("浏览器起不来: %v", err) }defer browser.Close()// 新建页面 page, err := browser.NewPage()if err != nil { log.Fatalf("新建页面失败: %v", err) }// 访问百度if _, err = page.Goto("https://www.baidu.com"); err != nil { log.Fatalf("打不开网页: %v", err) }// 截图保存if err = page.Screenshot(playwright.PageScreenshotOptions{ Path: playwright.String("baidu.png"), FullPage: playwright.Bool(true), // true表示截长图 }); err != nil { log.Fatalf("截图失败: %v", err) } log.Println("搞定!截图已保存")}
保存成main.go,然后运行:
go run main.go
不出意外的话,你会看到Chrome窗口弹出来,打开百度,然后"咔嚓"一声截图保存了。整个过程你不用管页面加载到哪儿了,playwright-go自己会等着。
再来个实用的:抓取Hacker News热榜
官方给的这个例子挺好的,咱们借鉴一下。抓取Hacker News首页的标题:
package mainimport ("fmt""log""github.com/playwright-community/playwright-go")funcmain() { pw, err := playwright.Run()if err != nil { log.Fatalf("could not start playwright: %v", err) } browser, err := pw.Chromium.Launch()if err != nil { log.Fatalf("could not launch browser: %v", err) } page, err := browser.NewPage()if err != nil { log.Fatalf("could not create page: %v", err) }// 访问Hacker Newsif _, err = page.Goto("https://news.ycombinator.com"); err != nil { log.Fatalf("could not goto: %v", err) }// 获取所有新闻条目 entries, err := page.Locator(".athing").All()if err != nil { log.Fatalf("could not get entries: %v", err) }for i, entry := range entries { title, err := entry.Locator("td.title > span > a").TextContent()if err != nil { log.Fatalf("could not get text content: %v", err) } fmt.Printf("%d: %s\n", i+1, title) } browser.Close() pw.Stop()}
这个例子展示了怎么用Locator定位元素,.All()获取所有匹配的元素,然后遍历取文本。
一些踩坑提醒
权限问题:在Linux上跑的时候,可能会报缺少某些系统库的错误。这时候--with-deps参数就很重要,或者手动装下缺失的依赖。
无头模式:默认是headless=true,也就是看不见窗口。调试的时候建议设成false,看着浏览器自己动挺有意思的,也能发现问题。
上下文隔离:如果你要模拟多个用户同时登录,别新开浏览器,用browser.NewContext()创建新上下文。每个上下文有独立的cookie、缓存,像开了隐身窗口一样,资源占用还小。
选择器写法:除了CSS选择器,还可以用文本定位,比如page.Locator("text=登录").Click(),这样不用管元素是啥class或id,更稳当。
跟Selenium比咋样
我是从Selenium转过来的,体感提升很明显:
- 速度快:启动浏览器和跑测试都比Selenium快一截
- 现代:支持Shadow DOM、WebSocket这些新玩意儿,对付现代前端框架写的页面更顺手
当然也有短板。Selenium毕竟年头久,社区资源多,遇到问题Stack Overflow上一搜一大把。playwright-go相对新一些,中文资料没那么多,不过官方文档还算全。
写在最后
如果你本来就是写Go的,又需要做浏览器自动化,真没必要为了用Selenium再去装一套Python环境。playwright-go直接把微软Playwright的强大功能封装成了Go的API,上手门槛不高,性能还更好。
而且它是社区维护的,开源免费,MIT协议,随便用。GitHub上star数一直在涨,最近还看到有MCP(Model Context Protocol)的集成,能让AI直接操控浏览器,玩法越来越多了。
总之,值得一试。花十分钟装好,写个脚本跑起来,你会发现自动化测试这事儿原来可以这么顺。
项目地址:https://github.com/playwright-community/playwright-go