sunty
2021-06-03 72ccf8a395203671f8a1e80d04c7418544f315f9
reptile first commit
6个文件已添加
242 ■■■■■ 已修改文件
code/code.go 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/reptileControllers.go 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/router.go 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/util.go 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code/code.go
New file
@@ -0,0 +1,17 @@
package code
import "net/http"
// Code 错误输出数据结构
type Code struct {
    Status  int    `json:"status"`  // HTTP 状态
    Success bool   `json:"success"` // 成功或者失败
    Message string `json:"msg"`     // 描述信息
}
var (
    // Success 请求处理成功
    Success = &Code{http.StatusOK, true, "请求处理成功"}
    // RequestParamError 请求参数错误
    RequestParamError = &Code{http.StatusBadRequest, false, "请求参数有误"}
)
controllers/reptileControllers.go
New file
@@ -0,0 +1,108 @@
package controllers
import (
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/gocolly/colly"
    "log"
    "reptile/code"
    "reptile/util"
)
type ReptileControllers struct{}
type FieldSelectorInfo struct {
    Name     string `json:"name"`
    Selector string `json:"selector"`
}
type FieldResult struct {
    Name  string
    Value string
}
type ReptileInfo struct {
    Url              string              `json:"url"`
    UserName         string              `json:"userName"`
    UserPassWD       string              `json:"userPassWD"`
    TitleSelectorStr string              `json:"titleSelectorStr"`
    ListSelectorStr  string              `json:"listSelectorStr"`
    ListRequest      bool                `json:"listRequest"`
    FspArray         []FieldSelectorInfo `json:"fspArray"`
}
func (rc *ReptileControllers) Reptile(c *gin.Context) {
    var rpif ReptileInfo
    c.BindJSON(&rpif)
    url := rpif.Url
    titleSelectorStr := rpif.TitleSelectorStr
    listSelectorStr := rpif.ListSelectorStr
    fspArray := rpif.FspArray
    listRequest := rpif.ListRequest
    if listRequest == true {
        if url != "" && titleSelectorStr != "" && listSelectorStr != "" && fspArray != nil && len(fspArray) > 0 {
            res := ReptileList(url, titleSelectorStr, listSelectorStr, fspArray)
            util.ResponseFormat(c, code.Success, res)
            return
        } else {
            util.ResponseFormat(c, code.RequestParamError, "请求参数有误")
            return
        }
    } else {
        if url != "" && titleSelectorStr != "" && fspArray != nil && len(fspArray) > 0 {
            res := ReptileNoList(url, titleSelectorStr, fspArray)
            util.ResponseFormat(c, code.Success, res)
            return
        } else {
            util.ResponseFormat(c, code.RequestParamError, "请求参数有误")
            return
        }
    }
    return
}
func ReptileList(url string, titleSelectorStr string, listSelectorStr string, fspArray []FieldSelectorInfo) interface{} {
    cy := colly.NewCollector()
    rfr := make([]interface{}, 0)
    cy.OnHTML(titleSelectorStr, func(e *colly.HTMLElement) {
        fmt.Println("+++++++++++++++++++++++++++")
        e.ForEach(listSelectorStr, func(i int, ele *colly.HTMLElement) {
            fr := []FieldResult{}
            for _, v := range fspArray {
                fr = append(fr, FieldResult{
                    Name:  v.Name,
                    Value: ele.ChildText(v.Selector),
                })
            }
            rfr = append(rfr, fr)
        })
    })
    err := cy.Request("GET", url, nil, nil, nil)
    if err != nil {
        log.Fatal("connect error: ", err)
    }
    return rfr
}
func ReptileNoList(url string, titleSelectorStr string, fspArray []FieldSelectorInfo) []interface{} {
    c := colly.NewCollector()
    rfr := make([]interface{}, 0)
    titleSelectorStr = "body"
    c.OnHTML(titleSelectorStr, func(e *colly.HTMLElement) {
        fmt.Println("+++++++++++++++++++++++++++")
        fr := []FieldResult{}
        for _, v := range fspArray {
            fmt.Println("v.Selector: ", v.Selector)
            fr = append(fr, FieldResult{
                Name:  v.Name,
                Value: e.DOM.Find(v.Selector).Eq(0).Text(),
            })
        }
        rfr = append(rfr, fr)
    })
    err := c.Request("GET", url, nil, nil, nil)
    if err != nil {
        log.Fatal("connect error: ", err)
    }
    return rfr
}
go.mod
New file
@@ -0,0 +1,16 @@
module reptile
go 1.12
require (
    github.com/PuerkitoBio/goquery v1.6.0 // indirect
    github.com/antchfx/htmlquery v1.2.3 // indirect
    github.com/antchfx/xmlquery v1.3.3 // indirect
    github.com/gin-gonic/gin v1.6.3
    github.com/gobwas/glob v0.2.3 // indirect
    github.com/gocolly/colly v1.2.0
    github.com/kennygrant/sanitize v1.2.4 // indirect
    github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
    github.com/temoto/robotstxt v1.1.1 // indirect
    google.golang.org/appengine v1.6.7 // indirect
)
main.go
New file
@@ -0,0 +1,60 @@
package main
import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "mime/multipart"
    "net/http"
    "reptile/router"
    "time"
)
func main() {
    r := router.NewRouter()
    r.Run("0.0.0.0:7070")
}
func GetLoginToken(method string, url string, parama []byte) (buf []byte, err error) {
    //defer elapsed("page")()
    timeout := time.Duration(100 * time.Second)
    client := http.Client{
        Timeout: timeout,
    }
    //loginInfo :=`{"login":"stybd","password":"suntianyu2486"}`
    p := new(bytes.Buffer)
    w := multipart.NewWriter(p)
    content_type := w.FormDataContentType()
    //w.WriteField("username","basic")
    //w.WriteField("password","basic2019")
    //w.Close()
    //logif := "login=stybd,password=suntianyu2486"
    request, err := http.NewRequest(method, url, p)
    request.Header.Set("Content-Type", content_type)
    if err != nil {
        fmt.Println("build request fail !")
        return nil, err
    }
    resp, err := client.Do(request)
    if err != nil {
        fmt.Println("request error: ", err)
        return nil, err
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
        return nil, err
    }
    var info interface{}
    json.Unmarshal(body, &info)
    fmt.Println("access_token:   ", info)
    fmt.Println("body:   ", resp.StatusCode)
    return body, nil
}
router/router.go
New file
@@ -0,0 +1,20 @@
package router
import (
    "github.com/gin-gonic/gin"
    "reptile/controllers"
)
func NewRouter() *gin.Engine {
    r := gin.Default()
    reptile := new(controllers.ReptileControllers)
    urlPrefix := "/basic/api-v"
    reptileApi := r.Group(urlPrefix + "/reptile")
    {
        reptileApi.POST("/reptile", reptile.Reptile)
    }
    return r
}
util/util.go
New file
@@ -0,0 +1,21 @@
package util
import (
    "github.com/gin-gonic/gin"
    "reptile/code"
)
//
// ResponseFormat 返回数据格式化
func ResponseFormat(c *gin.Context, respStatus *code.Code, data interface{}) {
    if respStatus == nil {
        respStatus = code.RequestParamError
    }
    c.JSON(respStatus.Status, gin.H{
        "code":    respStatus.Status,
        "success": respStatus.Success,
        "msg":     respStatus.Message,
        "data":    data,
    })
    return
}