Golang的首个爬虫程序

1、实现的思路

(1)、将网页加载到WebView里面,获取到页面的Cookie,通过标签的ID和属性,获取到验证码的图片;
(2)、将图片下载到本地(通过使用同一个图片链接请求图片可以发现,每次请求的图片内容都不一样,所以下载图片的时候需带上Cookie,表示图片已刷新了),通过调用科大讯飞的API识别图片上的内容;
(3)、通过用户名,密码,验证码调用登录的接口(具体的接口名称和参数去网页上找);
(4)、登录成功之后,这个Cookie和用户信息对应上,Cookie就生效了,就可以使用这个Cookie去调用其他的接口了。

2、具体的实现

func main() {
    go func() {
        ser := server.Default()//服务器初始化
        //用这个接口测试
        ser.GET("/GetTestData",TestTimer)
        ser.RunServer()
    }()
    //加载WebView页面,mac 下webview用OC实现的,windows用java
    Get("http://bhz.clkr.kxlims.cn/MsSys/Login")
}
//加载WebView页面
func Get(URL string) {
    w = webview.New(webview.Settings{
        Width:  800,
        Height: 600,
        Title:  "Simple canvas demo",
        URL:    URL,
        ExternalInvokeCallback: handleRPC,
        ExternalFinishLoadForFrameCallback:didFinishLoadForFrame,
    })
    defer w.Exit()
    w.Run()
    // Open wikipedia in a 800x600 resizable window
}
func handleRPC(w webview.WebView, data string) {
    fmt.Println("data:",data)
}
//加载成功之后调用方法
func didFinishLoadForFrame(w webview.WebView) {

    fmt.Start()
    if w.IsLoading() {
        fmt.Println("didFinishLoadForFrame IsLoading")
    } else {

        fmt.Println("didFinishLoadForFrame  not IsLoading",w.LoadUrl())
        fmt.Println("Cookie:",w.GetCookie())
        cookie := w.GetCookie()
        //w.ClearCache()
        list := strings.Split(cookie,"&")
        c := make(map[string]interface{})
        for _,value := range list {
            l := strings.Split(value,"=")
            if len(l) > 0 {
                c[l[0]] = l[1]
            }
        }
        if strings.EqualFold( c["name"].(string) ,"ASP.NET_SessionId") {
            test.CookieData = c["name"].(string) + "=" + c["value"].(string)
        }
        //w.StringByEvaluatingJavaScriptFromString(`alert($("#valiCode").attr("src"))`)
        //jquary 通过ID和属性,获取元素的值
        test.Pic = "http://bhz.clkr.kxlims.cn" + w.StringByEvaluatingJavaScriptFromString_2(`$("#valiCode").attr("src")`)
        //下载文件,注意:在请求下载图片的时候,需要带上Cookie,才会认为是刷新了验证码,否则会出现服务器存储的验证码和下载的验证码不相同的情况,则验证不通过
        test.DownloadFileTest(test.Pic,"./test.jpeg")
        //读取图片上的验证码,有免费的、付费的OCR识别的API,此处是调用的科大讯飞的免费API
        test.Content = test.OCRTest("./test.jpeg")
    }
    fmt.Over()
}
//测试接口的方法
func TestTimer(c *gin.Context) {
    //刷新页面
    //w.Dispatch(func() {
    //    w.StringByEvaluatingJavaScriptFromString(`window.location.reload()`)
    //})
    UserLogin(test.Content)
    var list []interface{}
    //如果这个接口调用成功,则前面的功能都成功
    //用封装好的GET请求的方法,GET请求的时候Header里面加上cookie
    data := GETS("http://bhz.clkr.kxlims.cn/MsSys/BhzOper/GetBhzBhjList?TargetId=01ae342a-9dc3-4d3d-bd50-df0b5370877d", test.CookieData)
    fmt.Println("data---->",data)
    err := json.Unmarshal([]byte(data), &list)
    if err != nil {
        fmt.Println("errAAAA:", err)
        return
    }
}
//模拟用户登录操作,使Cookie生效
func UserLogin(code string){
    jar,_ := cookiejar.New(nil)
    client := &http.Client{
        Jar:jar,
    }
    var resp *http.Response
    payload := strings.NewReader("Account=accout&Password=xxxxxx&ValidateCode=" + code)
    req, _ := http.NewRequest("POST", "http://bhz.clkr.kxlims.cn/MsSys/Login/CheckLogin", payload)
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Cookie", test.CookieData)
    resp, err := client.Do(req)
    if(resp != nil && resp.Body != nil) {
        defer resp.Body.Close()
    } else {
        fmt.Println("ERROR http://bhz.clkr.kxlims.cn/MsSys/Login/CheckLogin 返回为空 ")
    }
    if resp == nil || resp.Body == nil || err != nil {
        return
    }
    // 打印正文信息
    var buf []byte
    buf, err = ioutil.ReadAll(resp.Body)
    if(err != nil) {
        fmt.Println("err--->",err)
        return
    }
    varr map[string]interface{}
    json.Unmarshal(buf,&r)
    fmt.Println("r---->",r)
    if r["Result"].(float64) == 300{
        //登录成功,Cookie生效
        fmt.Println("登录成功,Cookie生效")
    }
}

发布了8 篇原创文章 · 获赞 1 · 访问量 9100

猜你喜欢

转载自blog.csdn.net/xiaoxiao_haiyan/article/details/81319949