推荐几个chrome debug protocol 库,直接面向 chrome debug protocol api
chromedp 截图示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main
import (
"context"
"io/ioutil"
"log"
"github.com/chromedp/chromedp"
)
func main() {
// create context
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// run task list
var buf []byte
err := chromedp.Run(ctx, screenshot(`https://www.google.com/`, `#main`, &buf))
if err != nil {
log.Fatal(err)
}
// save the screenshot to disk
if err = ioutil.WriteFile("screenshot.png", buf, 0644); err != nil {
log.Fatal(err)
}
}
func screenshot(urlstr, sel string, res *[]byte) chromedp.Tasks {
return chromedp.Tasks{
chromedp.Navigate(urlstr),
chromedp.WaitVisible(sel, chromedp.ByID),
chromedp.Screenshot(sel, res, chromedp.NodeVisible, chromedp.ByID),
}
}
godet 截图等示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
import "fmt"
import "time"
import "github.com/raff/godet"
func main() {
// connect to Chrome instance
remote, err := godet.Connect("localhost:9222", false)
if err != nil {
fmt.Println("cannot connect to Chrome instance:", err)
return
}
// disconnect when done
defer remote.Close()
// get browser and protocol version
version, _ := remote.Version()
fmt.Println(version)
// get list of open tabs
tabs, _ := remote.TabList("")
fmt.Println(tabs)
// install some callbacks
remote.CallbackEvent(godet.EventClosed, func(params godet.Params) {
fmt.Println("RemoteDebugger connection terminated.")
})
remote.CallbackEvent("Network.requestWillBeSent", func(params godet.Params) {
fmt.Println("requestWillBeSent",
params["type"],
params["documentURL"],
params["request"].(map[string]interface{})["url"])
})
remote.CallbackEvent("Network.responseReceived", func(params godet.Params) {
fmt.Println("responseReceived",
params["type"],
params["response"].(map[string]interface{})["url"])
})
remote.CallbackEvent("Log.entryAdded", func(params godet.Params) {
entry := params["entry"].(map[string]interface{})
fmt.Println("LOG", entry["type"], entry["level"], entry["text"])
})
// block loading of most images
_ = remote.SetBlockedURLs("*.jpg", "*.png", "*.gif")
// create new tab
tab, _ := remote.NewTab("https://www.google.com")
fmt.Println(tab)
// enable event processing
remote.RuntimeEvents(true)
remote.NetworkEvents(true)
remote.PageEvents(true)
remote.DOMEvents(true)
remote.LogEvents(true)
// navigate in existing tab
_ = remote.ActivateTab(tabs[0])
//remote.StartPreciseCoverage(true, true)
// re-enable events when changing active tab
remote.AllEvents(true) // enable all events
_, _ = remote.Navigate("https://www.google.com")
// evaluate Javascript expression in existing context
res, _ := remote.EvaluateWrap(`
console.log("hello from godet!")
return 42;
`)
fmt.Println(res)
// take a screenshot
_ = remote.SaveScreenshot("screenshot.png", 0644, 0, true)
time.Sleep(time.Second)
// or save page as PDF
_ = remote.SavePDF("page.pdf", 0644, godet.PortraitMode(), godet.Scale(0.5), godet.Dimensions(6.0, 2.0))
// if err := remote.SetInputFiles(0, []string{"hello.txt"}); err != nil {
// fmt.Println("setInputFiles", err)
// }
time.Sleep(5 * time.Second)
//remote.StopPreciseCoverage()
r, err := remote.GetPreciseCoverage(true)
if err != nil {
fmt.Println("error profiling", err)
} else {
fmt.Println(r)
}
// Allow downloads
_ = remote.SetDownloadBehavior(godet.AllowDownload, "/tmp/")
_, _ = remote.Navigate("http://httpbin.org/response-headers?Content-Type=text/plain;%20charset=UTF-8&Content-Disposition=attachment;%20filename%3d%22test.jnlp%22")
time.Sleep(time.Second)
// Block downloads
_ = remote.SetDownloadBehavior(godet.DenyDownload, "")
_, _ = remote.Navigate("http://httpbin.org/response-headers?Content-Type=text/plain;%20charset=UTF-8&Content-Disposition=attachment;%20filename%3d%22test.jnlp%22")
}
gcd 截图示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import (
"encoding/base64"
"flag"
"fmt"
"log"
"net/url"
"os"
"runtime"
"sync"
"time"
"github.com/wirepair/gcd"
"github.com/wirepair/gcd/gcdapi"
)
const (
numTabs = 5
)
var debugger *gcd.Gcd
var wg sync.WaitGroup
var path string
var dir string
var port string
func init() {
switch runtime.GOOS {
case "windows":
flag.StringVar(&path, "chrome", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", "path to chrome")
flag.StringVar(&dir, "dir", "C:\\temp\\", "user directory")
case "darwin":
flag.StringVar(&path, "chrome", "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "path to chrome")
flag.StringVar(&dir, "dir", "/tmp/", "user directory")
case "linux":
flag.StringVar(&path, "chrome", "/usr/bin/chromium-browser", "path to chrome")
flag.StringVar(&dir, "dir", "/tmp/", "user directory")
}
flag.StringVar(&port, "port", "9222", "Debugger port")
}
func main() {
var err error
urls := []string{"http://www.google.com", "http://www.veracode.com", "http://www.microsoft.com", "http://bbc.co.uk", "http://www.reddit.com/r/golang"}
flag.Parse()
debugger = gcd.NewChromeDebugger()
debugger.StartProcess(path, dir, port)
defer debugger.ExitProcess()
targets := make([]*gcd.ChromeTarget, numTabs)
for i := 0; i < numTabs; i++ {
wg.Add(1)
targets[i], err = debugger.NewTab()
if err != nil {
log.Fatalf("error getting targets")
}
page := targets[i].Page
page.Enable()
targets[i].Subscribe("Page.loadEventFired", pageLoaded)
// navigate
navigateParams := &gcdapi.PageNavigateParams{Url: urls[i]}
_, _, _, err := page.NavigateWithParams(navigateParams)
if err != nil {
log.Fatalf("error: %s\n", err)
}
}
wg.Wait()
for i := 0; i < numTabs; i++ {
takeScreenShot(targets[i])
}
}
func pageLoaded(target *gcd.ChromeTarget, event []byte) {
target.Unsubscribe("Page.loadEventFired")
wg.Done()
}
func takeScreenShot(target *gcd.ChromeTarget) {
dom := target.DOM
page := target.Page
doc, err := dom.GetDocument(-1, true)
if err != nil {
fmt.Printf("error getting doc: %s\n", err)
return
}
debugger.ActivateTab(target)
time.Sleep(1 * time.Second) // give it a sec to paint
u, urlErr := url.Parse(doc.DocumentURL)
if urlErr != nil {
fmt.Printf("error parsing url: %s\n", urlErr)
return
}
fmt.Printf("Taking screen shot of: %s\n", u.Host)
screenShotParams := &gcdapi.PageCaptureScreenshotParams{Format: "png", FromSurface: true}
img, errCap := page.CaptureScreenshotWithParams(screenShotParams)
if errCap != nil {
fmt.Printf("error getting doc: %s\n", errCap)
return
}
imgBytes, errDecode := base64.StdEncoding.DecodeString(img)
if errDecode != nil {
fmt.Printf("error decoding image: %s\n", errDecode)
return
}
f, errFile := os.Create(u.Host + ".png")
defer f.Close()
if errFile != nil {
fmt.Printf("error creating image file: %s\n", errFile)
return
}
f.Write(imgBytes)
debugger.CloseTab(target)
}
总结
从体验上看,godet
比较简洁。
- https://github.com/chromedp/chromedp
- https://github.com/raff/godet -- 推荐
- https://github.com/wirepair/gcd
本文网址: https://golangnote.com/topic/261.html 转摘请注明来源