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
func main() {defer func(){err:= recover()if err != nil {println(err)}}()var url = "https://www.163.com"
3.2 创建一个在golang里面phantomJS创建一个phanomJS进程
if err := phantomjs.DefaultProcess.Open(); err != nil {panic(err)os.Exit(1)}defer phantomjs.DefaultProcess.Close()
3.3 创建phantomJS page设置请求headers和view port
3.4 截图并输出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)}}
3.5 完整代码 main.go
package mainimport ("github.com/benbjohnson/phantomjs""os""net/http")//https://github.com/benbjohnson/phantomjsfunc 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 headersrequestHeader := 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)}}
4. 使用go标准库创建截图微服务
4.1 main.go完成代码
// example of HTTP server that uses the captcha package.package mainimport ("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"`}func screen_shot(w http.ResponseWriter, r *http.Request) {//parse request parameters//接收客户端发送来的请求参数jsondecoder := json.NewDecoder(r.Body)var postParameters jsonBodyerr := 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 = uriconfig.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 headersrequestHeader := 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 := "./"+OutputDirhttp.Handle(pathPrefix,http.StripPrefix(pathPrefix, http.FileServer(http.Dir(staticDir))))//api for create captchahttp.HandleFunc("/api/shot", screen_shot)fmt.Println("Server is at localhost:1122")if err := http.ListenAndServe("localhost:1122", nil); err != nil {log.Fatal(err)}}
4.2 PostmanAPI接口
4.3 返回参数
{"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"}
4.4 截图图片地址
http://localhost:1122/ + output_uri
