原文:https://zhuanlan.zhihu.com/p/438257924
这个可以形成一个web工具,专门用于帮助网友保存网址的截图。
package main
import (
"context"
"flag"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"time"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
type Chrome struct {
Url string
UserAgent string
FullScreen bool
ResolutionX int
ResolutionY int
Delay int64
}
var ChromeType *Chrome
// 初始化输入
func init() {
ChromeType = new(Chrome)
flag.StringVar(&ChromeType.Url, "url", "", "web http or https url (must)")
flag.BoolVar(&ChromeType.FullScreen, "F", false, "full screenshots auto width and height")
flag.StringVar(&ChromeType.UserAgent, "userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36", "user agent string to use")
flag.IntVar(&ChromeType.ResolutionX, "resolutionX", 1920, "screenshot resolution x")
flag.IntVar(&ChromeType.ResolutionY, "resolutionY", 1080, "screenshot resolution y")
flag.Int64Var(&ChromeType.Delay, "delay", 0, "delay in seconds between navigation and screenshot")
flag.Parse()
}
// 网页截屏小工具
func main() {
if ChromeType.Url == "" {
panic("url must input!")
}
buf, err := ChromeType.Screenshot()
if err != nil {
panic(err.Error())
}
fp := ChromeType.SafeFileName()
if err = ioutil.WriteFile(fp, buf, 0644); err != nil {
panic(err.Error())
}
thisPath, _ := os.Getwd()
log.Println("生成成功,文件名是:", filepath.Join(thisPath, fp))
}
func (chrome *Chrome) Screenshot() ([]byte, error) {
// 组装 chromeDp的参数设置
var options []chromedp.ExecAllocatorOption
options = append(options, chromedp.DefaultExecAllocatorOptions[:]...)
options = append(options, chromedp.UserAgent(chrome.UserAgent))
options = append(options, chromedp.DisableGPU)
options = append(options, chromedp.Flag("ignore-certificate-errors", true))
options = append(options, chromedp.WindowSize(chrome.ResolutionX, chrome.ResolutionY)) // 分辨率生成
actX, aCancel := chromedp.NewExecAllocator(context.Background(), options...)
ctx, cancel := chromedp.NewContext(actX)
defer aCancel()
defer cancel()
var buf []byte
// 压缩js对话框 如:alert()
chromedp.ListenTarget(ctx, func(ev interface{}) {
if _, ok := ev.(*page.EventJavascriptDialogOpening); ok {
go func() {
if err := chromedp.Run(ctx,
page.HandleJavaScriptDialog(true),
); err != nil {
panic(err)
}
}()
}
})
// 是否全屏
if chrome.FullScreen {
if err := chromedp.Run(ctx, chromedp.Tasks{
chromedp.Navigate(chrome.Url),
chromedp.Sleep(time.Duration(chrome.Delay) * time.Second),
chromedp.FullScreenshot(&buf, 100),
}); err != nil {
return nil, err
}
} else {
// 不是全屏下就直接生成
if err := chromedp.Run(ctx, chromedp.Tasks{
chromedp.Navigate(chrome.Url),
chromedp.Sleep(time.Duration(chrome.Delay) * time.Second),
chromedp.CaptureScreenshot(&buf),
}); err != nil {
return nil, err
}
}
return buf, nil
}
// SafeFileName 生成安全文件名,且生成png后缀的地址
func (chrome *Chrome) SafeFileName() string {
name := strings.ToLower(chrome.Url)
name = strings.Trim(name, " ")
separators, err := regexp.Compile(`[ &_=+:/]`)
if err == nil {
name = separators.ReplaceAllString(name, "-")
}
legal, err := regexp.Compile(`[^[:alnum:]-.]`)
if err == nil {
name = legal.ReplaceAllString(name, "")
}
for strings.Contains(name, "--") {
name = strings.Replace(name, "--", "-", -1)
}
return name + `.png`
}