使用 golang 辅助查询网约车信息

前些日子,收到一个做网约车的朋友的需求,他手下目前有几百号司机和车子。每隔1个月需要去交警队官方网站查询车和人的信息:

车:是否预约出租客运

人:是否有从业资格

 

流程大致如下:

1. 内部系统调用本服务,传入车和人的信息

2. 本服务去交管局网站查询

难点在于查询网站有个验证码,当然这也是他请我帮忙做的原因吧,谈好价格后,开干!

大致解决方案:

1. 使用 golang 搭建一个web站点

2. 接受参数后,去交管局网站查询

3. 模拟访问查询网站,下载验证码和cookie

4. 破解验证码

5. 模拟查询网站提交查询信息

6. 返回查询结果给调用者

验证码我使用的是百度AI文字识别方案,经测试,识别效果很好,但是有日使用次数限制。

 

部分源代码:

package openapi

import (
	"fmt"
    "strings"
    // "strconv"
	// "bytes"
    "os"
    // "io"
	"net/http"
	"net/url"
	// "time"
	"io/ioutil"
	"encoding/json"
	"encoding/base64"
	"errors"
	"github.com/astaxie/beego"
)

type BaiduAI struct {
	ApiKey string
	SecretKey string
}

func (this *BaiduAI) setApi(){
	this.ApiKey = "###"
	this.SecretKey = "###"
}

func (this *BaiduAI) GetToken() (string, error){
	if len(this.ApiKey) == 0{
		this.setApi()
	}

	//beego.AppConfig.Set("baidu_ai_access_token", this.SecretKey)
	str := beego.AppConfig.String("baidu_ai_access_token")

	if str  != "0"{
		return str , nil
	}

	urlstr := "https://aip.baidubce.com/oauth/2.0/token"
	v := url.Values{}
    v.Add("client_id", this.ApiKey)
	v.Add("client_secret", this.SecretKey)
	v.Add("grant_type", "client_credentials")
    param := v.Encode()
	reqest, _ := http.NewRequest("POST", urlstr, strings.NewReader(param))
	reqest.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
   
	client := &http.Client{}
	response, err := client.Do(reqest)
	if(err != nil){
	   defer response.Body.Close()
	   return "", err
	}
	
	body, _ := ioutil.ReadAll(response.Body)
	content := string(body)
	fmt.Println("BAIDU API TOKEN :" , content)

	m := map[string]interface{}{}
	errx := json.Unmarshal([]byte(content), &m)

	if errx != nil {
		return "", errx
	}

	token := m["access_token"].(string)
	beego.AppConfig.Set("baidu_ai_access_token", token)
	return token, nil
}

func (this *BaiduAI) TryGetBase64Captcha(path string) (string, error){
	// File
	file, err := os.Open(path)
	if err != nil {
		fmt.Println("打开图片出错", err)
		fmt.Println(err)
		os.Exit(-1)
	}
	defer file.Close()

    // FileInfo
	stats, err := file.Stat()
    if err != nil {
        return "", err
	}

	// []byte
    data := make([]byte, stats.Size())
    _, err = file.Read(data)
    if err != nil {
         return "", err
    }

	base64str := base64.StdEncoding.EncodeToString(data)
	fmt.Println("data:image/jpg;base64,", base64str)

	return base64str, nil
}

// 尝试解开图形验证码
func (this *BaiduAI) TryGetCaptchaValue(path string) (string, error){

	base64, err := this.TryGetBase64Captcha(path)
	if err != nil{
		return "", err
	} 

	access_token, err := this.GetToken()
	if err != nil{
		return "", err
	}

	// doc page : https://ai.baidu.com/ai-doc/OCR/Ok3h7y1vo

	urlstr := "https://aip.baidubce.com/rest/2.0/ocr/v1/numbers?access_token=" + access_token
	v := url.Values{}
	v.Add("recognize_granularity", "big")
	v.Add("detect_direction", "false")
	v.Add("image", base64)
	param := v.Encode()
	
	reqest, _ := http.NewRequest("POST", urlstr, strings.NewReader(param))
	reqest.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
   
	client := &http.Client{}
	response, err := client.Do(reqest)
	if(err != nil){
	   defer response.Body.Close()
	   return "", err
	}
	
	body, _ := ioutil.ReadAll(response.Body)
	content := string(body)
	fmt.Println("百度AI 图片识别结果 :" , content)
 
	return this.readJson(content)
}

func (this *BaiduAI) readJson(jsonstr string) (string, error){

	map_result := map[string]interface{}{}
	errx := json.Unmarshal([]byte(jsonstr), &map_result)
	if errx != nil {
		return "", errx
	}

	words_result_num, ok := map_result["words_result_num"]
	if !ok {
		return jsonstr, nil
	}

	int_nm := words_result_num.(float64)

	if int_nm == 0 {
		return "", errors.New("未能识出此验证码,请重试")
	}

	words_result := map_result["words_result"]

	arr_result := words_result.([]interface{})
	fmt.Println(arr_result[0]);

	map_end := arr_result[0].(map[string]interface {})

	
	fmt.Println("2222222222222222222222222222222222222");
	fmt.Println(map_end["words"].(string));

	words := map_end["words"].(string)

	return words, nil
}

  

原文地址:https://www.cnblogs.com/chenrh/p/12027824.html