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"
}
}
伸手党可能有点烦,因为还是需要改一下才能运行的。主要就是一个网页截图以及展示图片。