💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] > https://github.com/chromedp/chromedp > [官方exmaples](https://github.com/chromedp/examples/blob/master/click/main.go) ## 概述 - 用于控制和自动化谷歌 Chrome 浏览器或 Chromium 浏览器。 - 它提供了一种以编程方式操作浏览器的方法,从而允许开发者执行各种自动化任务,如网页截图、网页爬取、表单填写、页面导航等 - 可提供无头浏览器和调启浏览器 ## 与seleiumt 区别 - 底层实现技术: - Selenium:Selenium 是一个跨浏览器的自动化测试框架,它使用浏览器的原生驱动程序(如Chrome WebDriver、Firefox WebDriver等)来控制浏览器。因此,它支持多种浏览器,但需要相应的驱动程序。 - chromedp:chromedp 是一个专门用于控制 Chrome 浏览器的 Go 语言库,它使用 Chrome DevTools Protocol 与浏览器进行通信。因此,它主要用于自动化 Chrome 浏览器。 - 编程语言: - Selenium:Selenium 提供多种编程语言的客户端库,包括 Java、Python、C#、JavaScript等,使开发人员可以选择适合自己的语言来编写测试脚本。 - chromedp:chromedp 是一个 Go 语言库,因此主要用于 Go 语言开发。如果您使用 Go 语言,它是一个强大的选择。 - 社区和生态系统: - Selenium:Selenium 有一个广泛的社区支持和大量的扩展库,可以用于各种自动化测试需求。它有许多资源和社区,可以解决各种问题。 - chromedp:chromedp 是相对较新的项目,因此它的生态系统相对较小。但是,它仍然在不断发展,可以满足一些特定需求。 - 性能和效率: - chromedp:由于 chromedp 直接与 Chrome 浏览器通信,它可以提供更好的性能和效率,特别是在处理大规模的 web 自动化任务时。 - Selenium:Selenium 使用浏览器的驱动程序,可能在性能和效率方面略逊于 chromedp,尤其是在处理大量浏览器实例时。 - 跨浏览器支持: - Selenium:Selenium 是跨浏览器的,可以用于控制多种不同的浏览器。这使得它在需要在不同浏览器中进行测试的情况下非常有用。 - chromedp:chromedp 主要用于控制 Chrome 浏览器,因此在需要与其他浏览器进行交互的情况下,可能需要使用其他工具或库。 ## 常用参数 ``` chromedp.NewContext() 初始化chromedp的上下文,后续这个页面都使用这个上下文进行操作 chromedp.Run() 运行一个chrome的一系列操作 chromedp.Navigate() 将浏览器导航到某个页面 chromedp.WaitVisible() 等候某个元素可见,再继续执行。 chromedp.Click() 模拟鼠标点击某个元素 chromedp.Value() 获取某个元素的value值 chromedp.InnerHTML() 获取某个元素的内部html值 chromedp.OuterHTML() 获取某个元素的内部和本身html值 chromedp.ActionFunc() 再当前页面执行某些自定义函数 chromedp.Text() 读取某个元素的text值 chromedp.Evaluate() 执行某个js,相当于控制台输入js network.SetExtraHTTPHeaders() 截取请求,额外增加header头 chromedp.SendKeys() 模拟键盘操作,输入字符 chromedp.Nodes() 根据xpath获取某些元素,并存储进入数组 chromedp.NewRemoteAllocator chromedp.OuterHTML() 获取元素的outer html chromedp.Screenshot() 根据某个元素截图 page.CaptureScreenshot() 截取整个页面的元素 chromedp.Submit() 提交某个表单 chromedp.WaitNotPresent() 等候某个元素不存在,比如“正在搜索。。。” ``` ## 技巧 ### 显示浏览器 ``` opts := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.Flag("headless", false), ) allocator, cancelFunc := chromedp.NewExecAllocator(context.Background(), opts...) defer cancelFunc() // create chrome instance ctx, cancel := chromedp.NewContext( allocator, chromedp.WithLogf(log.Printf), ) defer cancel() ``` ### Click ``` err := chromedp.Run(ctx, chromedp.Navigate(`https://pkg.go.dev/time`), // wait for footer element is visible (ie, page is loaded) chromedp.WaitVisible(`body > footer`), // find and click "Example" link chromedp.Click(`#example-After`, chromedp.NodeVisible), // retrieve the text of the textarea chromedp.Value(`#example-After textarea`, &example), ) ``` ### cookie 读写 ``` err := chromedp.Run(ctx, chromedp.ActionFunc(func(ctx context.Context) error { expr := cdp.TimeSinceEpoch(time.Now().Add(180 * 24 * time.Hour)) err := network.SetCookie("PHPSESSID", "pru4459rc52gsljq3a138rvh4r"). WithExpires(&expr). WithDomain("www.kancloud.cn"). // 此参数必填,否则无法跳转url WithHTTPOnly(true). Do(ctx) if err != nil { return err } return nil }), chromedp.Navigate("https://www.kancloud.cn/"), chromedp.ActionFunc(func(ctx context.Context) error { cookies, err := storage.GetCookies().Do(ctx) if err != nil { return err } for i, cookie := range cookies { log.Printf("chrome cookie %d: %+v", i, cookie) } return nil }), ) ``` ### SendKeys 用于模拟键盘输入 ``` err := chromedp.Run(ctx, chromedp.Navigate("https://example.com"), chromedp.SendKeys("#username", "myusername"), ) ``` ### Value / Text Value 获取 表单元素的值 ``` err := chromedp.Run(ctx, chromedp.Navigate(`https://pkg.go.dev/time`), chromedp.Value(`.js-buildContextSelect`, &res, chromedp.NodeVisible), ) ``` Text 获取标签中内容的值 ``` ``` ### InnerHTML / OuterHTML 获取值 ``` var usernameValue string err := chromedp.Run(ctx, chromedp.Navigate("https://example.com"), chromedp.Value("#username", &usernameValue), ) ``` `InnerHTML` 用于获取指定元素的内部 HTML 内容,即元素包含的所有子元素和文本内容 ``` var innerHTML string err := chromedp.Run(ctx, chromedp.Navigate("https://example.com"), chromedp.InnerHTML("#elementID", &innerHTML), ) ``` `OuterHTML` 用于获取指定元素及其包含的所有内容,包括元素本身和其内部的子元素、文本内容等 ``` var outerHTML string err := chromedp.Run(ctx, chromedp.Navigate("https://example.com"), chromedp.OuterHTML("#elementID", &outerHTML), ) ``` ### Screenshot 只截取info ``` var img []byte err := chromedp.Run(ctx, chromedp.Navigate(`https://www.kancloud.cn/`), chromedp.Screenshot(".info", &img), //只截取.info 的区域 ) if err != nil { log.Fatal(err) } os.WriteFile("aa.png", img, os.ModePerm) ``` 截图整个body ``` var img []byte err := chromedp.Run(ctx, chromedp.Navigate(`https://www.kancloud.cn/`), chromedp.Screenshot("body", &img), //截取整个 body ) if err != nil { log.Fatal(err) } os.WriteFile("aa.png", img, os.ModePerm) ``` ### FullScreenshot ``` var img []byte err := chromedp.Run(ctx, chromedp.Navigate(`https://www.kancloud.cn/`), chromedp.FullScreenshot(&img, 100), //截取整个 body ) if err != nil { log.Fatal(err) } os.WriteFile("aa.png", img, os.ModePerm) ``` ### PDF ``` var img []byte err := chromedp.Run(ctx, chromedp.Navigate(`https://www.kancloud.cn/`), chromedp.ActionFunc(func(ctx context.Context) error { img1, _, err := page.PrintToPDF().WithPrintBackground(false).Do(ctx) img = img1 return err }), ) if err != nil { log.Fatal(err) } os.WriteFile("aa.pdf", img, os.ModePerm) ``` ## 文件上传 ``` err := chromedp.Run(ctx, chromedp.Navigate("https://www.bejson.com/ui/compress_img/"), chromedp.SendKeys(`[type="file"]`, filepath, chromedp.NodeVisible), ) ``` ## runtime.Evaluate 执行自定义js ``` err := chromedp.Run(ctx, chromedp.Navigate("https://www.bejson.com/ui/compress_img/"), chromedp.ActionFunc(func(ctx context.Context) error { runtime.Evaluate(` alert("123"); `).Do(ctx) return nil }), ) ``` ### 等待元素可见 ``` err := chromedp.Run(ctx, chromedp.Navigate("https://www.bejson.com/ui/compress_img/"), chromedp.WaitVisible(`#box1`), chromedp.ActionFunc(func(context.Context) error { log.Printf(">>>>>>>>>>>>>>>>>>>> BOX1 IS VISIBLE") return nil }), ) ``` ### 使用XPath 选择节点[★] ``` err := chromedp.Run(ctx, chromedp.Navigate("https://www.baidu.com"), chromedp.Click(`//*[contains(text(),'网盘')]`), // 获取标签内容为 网盘的节点 ) ``` 更多XPATH 的学习查看 `/前端/XPATH`