基于Go语言和phantomJS的屏幕截图分享微服务

trytv · · 1595 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

背景

  • 前端程序员不愿意(技术不行)使用canvs截取图片分享到微信朋友圈

准备工作

  • *unix系统安装phantomJS可执行文件,phantomjs添加到系统环境变量
  • 检验phantomjs安装是否成功,在终端中运行$: phantomjs不报错,则安装成功
  • 安装go package github.com/benbjohnson/phantomjs,主要功能方便go调用phantomJS二进制文件命令

go调用phantomJS代码解析

  • defer函数捕捉panic

    func main() {
        defer func(){
    
            err:= recover()
            if err != nil {
                println(err)
            }
        }()
        var url = "https://www.163.com"
  • 创建一个在golang里面phantomJS创建一个phanomJS进程

    if err := phantomjs.DefaultProcess.Open(); err != nil {
        panic(err)
        os.Exit(1)
    }
    defer phantomjs.DefaultProcess.Close()
  • 创建phantomJS page设置请求headers和view port

    page, err := phantomjs.CreateWebPage()
    if err != nil {
        panic(err)
    }
    //set request headers 设置UserAgent为iPhone
    requestHeader := http.Header{
        "User-Agent" :[]string{"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"},
    }
    
    if err := page.SetCustomHeaders(requestHeader);err != nil {
        panic(err)
    }
    
    // Setup the viewport and render the results view.
    if err := page.SetViewportSize(640, 960); err != nil {
        panic(err)
    }
  • 截图并输出png文件

    // Open a URL.
    if err := page.Open(url); err != nil {
        panic(err)
    }
    if err := page.Render("hackernews4.png", "png", 50); err != nil {
        panic(err)
    }}
  • 完整代码
    main.go

      package main
    
      import (
          "github.com/benbjohnson/phantomjs"
          "os"
          "net/http"
      )
      
      //https://github.com/benbjohnson/phantomjs
      func main() {
          defer func(){
      
              err:= recover()
              if err != nil {
                  println(err)
              }
          }()
      
          var url = "https://www.163.com"
          // Start the process once.
          if err := phantomjs.DefaultProcess.Open(); err != nil {
              panic(err)
              os.Exit(1)
          }
      
          defer phantomjs.DefaultProcess.Close()
      
      
          page, err := phantomjs.CreateWebPage()
          if err != nil {
              panic(err)
          }
          //set request headers
          requestHeader := http.Header{
              "User-Agent" :[]string{"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"},
          }
      
          if err := page.SetCustomHeaders(requestHeader);err != nil {
              panic(err)
          }
      
          // Setup the viewport and render the results view.
          if err := page.SetViewportSize(640, 960); err != nil {
              panic(err)
          }
          // Open a URL.
          if err := page.Open(url); err != nil {
              panic(err)
          }
          if err := page.Render("163_news_screen_shot.png", "png", 50); err != nil {
              panic(err)
          }}

使用go标准库创建截图微服务

  • main.go完成代码
    // example of HTTP server that uses the captcha package.
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"
    "github.com/benbjohnson/phantomjs"
)

const OutputDir = "screen_shot"

//ConfigJsonBody json request body.
type jsonBody struct {
    Url              string `json:"url"`
    ViewportWidth     int `json:"viewport_width"`
    ViewportHeight     int `json:"viewport_height"`
    OutputFileName     string `json:"output_file_name"`
    OutputFileExt     string  `json:"output_file_ext"`
    Quility int `json:"quility"`
    OutputUri    string `json:"output_uri"`
}

// base64Captcha create http handler
func screen_shot(w http.ResponseWriter, r *http.Request) {
    //parse request parameters
    //接收客户端发送来的请求参数json
    decoder := json.NewDecoder(r.Body)
    var postParameters jsonBody
    err := decoder.Decode(&postParameters)
    if err != nil {
        log.Println(err)
    }
    defer r.Body.Close()
    //截图网页
    phantomjs_screen_shot(&postParameters)
    //set json response
    //设置json响应
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    body := map[string]interface{}{"code": 1, "data": postParameters, "msg": "success"}
    json.NewEncoder(w).Encode(body)
}

func phantomjs_screen_shot(config *jsonBody)  {
    uri := fmt.Sprintf("%s/%s", OutputDir,config.OutputFileName)
    config.OutputFileName = uri
    config.OutputUri = uri
    // Start the process once.
    if err := phantomjs.DefaultProcess.Open(); err != nil {
        panic(err)
        os.Exit(1)
    }
    defer phantomjs.DefaultProcess.Close()


    page, err := phantomjs.CreateWebPage()
    if err != nil {
        panic(err)
    }
    //set request headers
    requestHeader := http.Header{
        "User-Agent" :[]string{"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"},
    }

    if err := page.SetCustomHeaders(requestHeader);err != nil {
        panic(err)
    }

    // Setup the viewport and render the results view.
    if err := page.SetViewportSize(config.ViewportWidth, config.ViewportHeight); err != nil {
        panic(err)
    }
    // Open a URL.
    if err := page.Open(config.Url); err != nil {
        panic(err)
    }
    if err := page.Render(config.OutputFileName, config.OutputFileExt, config.Quility); err != nil {
        panic(err)
    }
}


//start a net/http server
//启动golang net/http 服务器
func main() {
    
    pathPrefix := "/"+OutputDir +"/"
    staticDir := "./"+OutputDir
    http.Handle(pathPrefix,http.StripPrefix(pathPrefix, http.FileServer(http.Dir(staticDir))))

    //api for create captcha
    http.HandleFunc("/api/shot", screen_shot)


    fmt.Println("Server is at localhost:1122")
    if err := http.ListenAndServe("localhost:1122", nil); err != nil {
        log.Fatal(err)
    }
}
  • postmanAPI接口
POST /api/shot HTTP/1.1
Host: localhost:1122
Content-Type: application/json
Cache-Control: no-cache

{
    "url":"http://www.163.com",
    "viewport_width":480,
    "viewport_height":960,
    "output_file_name":"awesome.jpg",
    "output_file_ext":"jpg",
    "quility":90
}
- 返回参数

{

"code": 1,
"data": {
    "url": "http://www.163.com",
    "viewport_width": 480,
    "viewport_height": 960,
    "output_file_name": "screen_shot/awesome.jpg",
    "output_file_ext": "jpg",
    "quility": 90,
    "output_uri": "screen_shot/awesome.jpg"
},
"msg": "success"

}


截图图片地址`localhost:1122/` + `output_uri`
  • todo::图片上传到阿里云oss
  • todo::相同url不重复截图

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:trytv

查看原文:基于Go语言和phantomJS的屏幕截图分享微服务

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

1595 次点击  
加入收藏 微博
1 回复  |  直到 2018-06-14 14:04:21
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传