1. 什么是Phantomjs


PhantomJS是一个基于webkit的JavaScript API。它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行JavaScript代码。任何您可以在基于webkit浏览器做的事情,它都能做到。它不仅是个隐形的浏览器,提供了诸如CSS选择器,支持Web标准、DOM操作、JSON、HTML5、Canvas、SVG等,同时也提供了处理文件I/O的操作,从而使您可以向操作系统读写文件等。PhantomJS的用处可谓非常广泛,诸如网络监测、网页截屏,无需浏览器的 Web 测试,页面访问自动化等.。

2. 准备工作


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

3. Go调用phantomJS代码解析
3.1 defer函数捕捉panic

  1. func main() {
  2. defer func(){
  3. err:= recover()
  4. if err != nil {
  5. println(err)
  6. }
  7. }()
  8. var url = "https://www.163.com"


3.2 创建一个在golang里面phantomJS创建一个phanomJS进程

  1. if err := phantomjs.DefaultProcess.Open(); err != nil {
  2. panic(err)
  3. os.Exit(1)
  4. }
  5. defer phantomjs.DefaultProcess.Close()


3.3 创建phantomJS page设置请求headers和view port
3.4 截图并输出png文件

  1. // Open a URL.
  2. if err := page.Open(url); err != nil {
  3. panic(err)
  4. }
  5. if err := page.Render("hackernews4.png", "png", 50); err != nil {
  6. panic(err)
  7. }
  8. }


3.5 完整代码 main.go

  1. package main
  2. import (
  3. "github.com/benbjohnson/phantomjs"
  4. "os"
  5. "net/http"
  6. )
  7. //https://github.com/benbjohnson/phantomjs
  8. func main() {
  9. defer func(){
  10. err:= recover()
  11. if err != nil {
  12. println(err)
  13. }
  14. }()
  15. var url = "https://www.163.com"
  16. // Start the process once.
  17. if err := phantomjs.DefaultProcess.Open(); err != nil {
  18. panic(err)
  19. os.Exit(1)
  20. }
  21. defer phantomjs.DefaultProcess.Close()
  22. page, err := phantomjs.CreateWebPage()
  23. if err != nil {
  24. panic(err)
  25. }
  26. //set request headers
  27. requestHeader := http.Header{
  28. "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"},
  29. }
  30. if err := page.SetCustomHeaders(requestHeader);err != nil {
  31. panic(err)
  32. }
  33. // Setup the viewport and render the results view.
  34. if err := page.SetViewportSize(640, 960); err != nil {
  35. panic(err)
  36. }
  37. // Open a URL.
  38. if err := page.Open(url); err != nil {
  39. panic(err)
  40. }
  41. if err := page.Render("163_news_screen_shot.png", "png", 50); err != nil {
  42. panic(err)
  43. }}

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

4.1 main.go完成代码

  1. // example of HTTP server that uses the captcha package.
  2. package main
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "os"
  9. "github.com/benbjohnson/phantomjs"
  10. )
  11. const OutputDir = "screen_shot"
  12. //ConfigJsonBody json request body.
  13. type jsonBody struct {
  14. Url string `json:"url"`
  15. ViewportWidth int `json:"viewport_width"`
  16. ViewportHeight int `json:"viewport_height"`
  17. OutputFileName string `json:"output_file_name"`
  18. OutputFileExt string `json:"output_file_ext"`
  19. Quility int `json:"quility"`
  20. OutputUri string `json:"output_uri"`
  21. }
  22. func screen_shot(w http.ResponseWriter, r *http.Request) {
  23. //parse request parameters
  24. //接收客户端发送来的请求参数json
  25. decoder := json.NewDecoder(r.Body)
  26. var postParameters jsonBody
  27. err := decoder.Decode(&postParameters)
  28. if err != nil {
  29. log.Println(err)
  30. }
  31. defer r.Body.Close()
  32. //截图网页
  33. phantomjs_screen_shot(&postParameters)
  34. //set json response
  35. //设置json响应
  36. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  37. body := map[string]interface{}{"code": 1, "data": postParameters, "msg": "success"}
  38. json.NewEncoder(w).Encode(body)
  39. }
  40. func phantomjs_screen_shot(config *jsonBody) {
  41. uri := fmt.Sprintf("%s/%s", OutputDir,config.OutputFileName)
  42. config.OutputFileName = uri
  43. config.OutputUri = uri
  44. // Start the process once.
  45. if err := phantomjs.DefaultProcess.Open(); err != nil {
  46. panic(err)
  47. os.Exit(1)
  48. }
  49. defer phantomjs.DefaultProcess.Close()
  50. page, err := phantomjs.CreateWebPage()
  51. if err != nil {
  52. panic(err)
  53. }
  54. //set request headers
  55. requestHeader := http.Header{
  56. "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"},
  57. }
  58. if err := page.SetCustomHeaders(requestHeader);err != nil {
  59. panic(err)
  60. }
  61. // Setup the viewport and render the results view.
  62. if err := page.SetViewportSize(config.ViewportWidth, config.ViewportHeight); err != nil {
  63. panic(err)
  64. }
  65. // Open a URL.
  66. if err := page.Open(config.Url); err != nil {
  67. panic(err)
  68. }
  69. if err := page.Render(config.OutputFileName, config.OutputFileExt, config.Quility); err != nil {
  70. panic(err)
  71. }
  72. }
  73. //start a net/http server
  74. //启动golang net/http 服务器
  75. func main() {
  76. pathPrefix := "/"+OutputDir +"/"
  77. staticDir := "./"+OutputDir
  78. http.Handle(pathPrefix,http.StripPrefix(pathPrefix, http.FileServer(http.Dir(staticDir))))
  79. //api for create captcha
  80. http.HandleFunc("/api/shot", screen_shot)
  81. fmt.Println("Server is at localhost:1122")
  82. if err := http.ListenAndServe("localhost:1122", nil); err != nil {
  83. log.Fatal(err)
  84. }
  85. }

4.2 PostmanAPI接口


4.3 返回参数

  1. {
  2. "code": 1,
  3. "data": {
  4. "url": "http://www.163.com",
  5. "viewport_width": 480,
  6. "viewport_height": 960,
  7. "output_file_name": "screen_shot/awesome.jpg",
  8. "output_file_ext": "jpg",
  9. "quility": 90,
  10. "output_uri": "screen_shot/awesome.jpg"
  11. },
  12. "msg": "success"
  13. }

4.4 截图图片地址

http://localhost:1122/ + output_uri

5. 参考资料