分享基于phantomjs的web截图

main.go
package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "io/ioutil"
    "net/http"
    "os/exec"
    "path"
    "runtime"
    "strconv"
    "strings"
    "sync"
    "time"
)


type App struct {
    Domain string
    Post   int
    ScreenJS   string
    ScreenPath string
    Static     string
}



type Config struct {
    Resource Resource
    RootDir  string //项目根目录
    App      *App
    Log      *log.Config
}

var curDir string

func init() {
    _, filename, _, _ := runtime.Caller(1)
    curDir = path.Dir(filename)
}

var rootCfg Config

func conf() Config {
    if rootCfg.RootDir == "" {
        rootCfg.RootDir = path.Join(curDir, "./")
        var f = rootCfg.RootDir + "/dsp_screen.json"
        data, err := ioutil.ReadFile(f)
        if err != nil {
            panic(err)
        }
        err = json.Unmarshal(data, &rootCfg)
        if err != nil {
            panic(err)
        }
    }
    return rootCfg
}

var dbs = make(map[string]*mongo.Mdb)
var mutex sync.Mutex


const shortFormat = "20060102"

//collection
const (
    ScreenCollection = "Screen"
)

//id_generator
const (
    idGenerator = "id_generator"
)

type Screen struct {
    Id         int64  `bson:"_id"`
    Url        string `bson:"Url"`
    UserAgent  string `bson:"UserAgent"`
    Path       string `bson:"Path"`
    CreateTime int64  `bson:"CreateTime"`
}

// func (this *Screen) Init() {
//     id := nextId(ScreenCollection)
//     this.Id = id
//     this.CreateTime = time.Now().Unix()
// }

// func (this *Screen) IsInit() bool {
//     return this.Id != 0
// }

// func (this *Screen) Save() (err error) {
//     return appMdb().Insert(ScreenCollection, this)
// }

func screen(rw http.ResponseWriter, req *http.Request) {
    defer req.Body.Close()
    data, err := ioutil.ReadAll(req.Body)
    if err != nil {
        WriteError(rw, err.Error())
        return
    }

    body := make(map[string]string)
    err = json.Unmarshal(data, &body)
    if err != nil {
        WriteError(rw, err.Error())
        return
    }

    screen := new(Screen)
    if url, ok := body["Url"]; ok {
        screen.Url = url
    }

    if data, ok := body["Data"]; ok {
        screen.UserAgent = fmt.Sprintf("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/38.0.2125.111 Chrome/38.0.2125.111 Safari/537.36?%s",
            data)
    }

    t := time.Now()
    screen.Path = fmt.Sprintf("%s/%d.png", t.Format(shortFormat), t.UnixNano())
    path := fmt.Sprintf("%s/%s", conf().App.ScreenPath, screen.Path)
    ph := exec.Command("phantomjs", conf().RootDir+"/"+conf().App.ScreenJS, screen.Url, screen.UserAgent, path)
    out, err := ph.Output()
    if err != nil {
        log.Error(err)
        WriteError(rw, err.Error())
        return
    }

    if strings.Contains(string(out), "false") {
        log.Error(string(out))
        WriteError(rw, "截图失败")
        return
    }

    // screen.Init()
    // err = screen.Save()
    // if err != nil {
    //     log.Error(err)
    //     WriteError(rw, err.Error())
    //     return
    // }

    result := make(map[string]string)
    result["url"] = conf().App.Domain + "/" + conf().App.Static + "/" + screen.Path
    WriteResult(rw, result)
}

func image(rw http.ResponseWriter, req *http.Request) {
    staticHandler := http.FileServer(http.Dir(conf().RootDir))
    staticHandler.ServeHTTP(rw, req)
    return
}

func WriteError(rw http.ResponseWriter, msg string) {
    rw.Write([]byte(`{"success":false,"message":"` + msg + `"}`))
}

func WriteResult(rw http.ResponseWriter, result interface{}) {
    data, err := json.Marshal(result)
    if err != nil {
        WriteError(rw, err.Error())
    } else {
        rw.Write([]byte(fmt.Sprintf(`{"success":false,"result":%s}`, string(data))))
    }
}

func handler(rw http.ResponseWriter, req *http.Request) {
    if strings.Contains(req.URL.String(), conf().App.Static) {
        image(rw, req)
    } else {
        screen(rw, req)
    }
}

func main() {
    err := log.InitConf(conf().Log)
    if err != nil {
        panic(err)
    }

    http.HandleFunc("/", handler)
    fmt.Println("监听端口", conf().App.Post)
    err = http.ListenAndServe(fmt.Sprintf(":%d", conf().App.Post), nil)
    if err != nil {
        log.Error(err)
        panic(err)
    }
}

 
  
phantomjs.js
var page = require('webpage').create();
page.paperSize = {
	width:'5in',
	height:'7in'
};


//args
//code word directory
if (phantom.args.length < 3) {
	console.log("{'success': false, 'result': '参数不正确'}");
	phantom.exit();
};
var args = phantom.args;
var url = args[0];
var userAgent  = args[1];
var path = args[2];


page.settings.userAgent = userAgent;
page.settings.viewportSize = { width: 1920, height: 1080 };
//设置超时
// page.settings.resourceTimeout = 10000;


page.viewportSize = { width: 1920, height : 1080 };
page.open(url, function(status) {
	if (status !== 'success') {
		console.log("{'success': false, 'result': '请求出错'}");
	} else {
		page.render(path)
		console.log("{'success': true, 'result': '"+path+"'}");
	}
	phantom.exit();
});


 
  
配置文件
{
    "App": {
    	"Domain":"http://localhost:9988",
    	"Post":9988,
        "ScreenJS":"phantom.js",
        "ScreenPath":"/data/screen/screen",
        "Static":"image"
    }
}


 伸手党可能有点烦,因为还是需要改一下才能运行的。主要就是一个网页截图以及展示图片。 
 

你可能感兴趣的:(编程实践,phantomjs,golang,网页截图服务器)