123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Package ocr 提供验证码识别服务。
- //
- // TODO: 迁移到 common/clients/ocr.go
- package ocr
- import (
- "context"
- "encoding/json"
- "io"
- "net/http"
- "net/url"
- "strings"
- "git.listensoft.net/tool/jspkit/logger"
- "go.uber.org/zap"
- )
- // DefaultOcrOption 是默认的验证码识别服务配置
- var DefaultOcrOption = OcrOption{
- User: user,
- Pass: pass,
- SoftId: softid,
- }
- const DefaultOcrURL = "http://upload.chaojiying.net"
- // OcrOption 是验证码识别服务的配置
- type OcrOption struct {
- User string
- Pass string
- SoftId string
- }
- // NewDefaultOcrClient 使用默认参数创建客户端
- func NewDefaultOcrClient() OcrClient {
- return OcrClient{
- Option: DefaultOcrOption,
- Client: http.DefaultClient,
- Logger: logger.GetLogger(),
- BaseURL: DefaultOcrURL,
- }
- }
- // OcrClient 是超级鹰验证码识别接口客户端。
- // 文档链接: https://www.chaojiying.com/api-5.html
- type OcrClient struct {
- Option OcrOption // 接口授权相关
- Client *http.Client // HTTP 客户端
- Logger *zap.Logger // 日志
- BaseURL string // 服务地址
- }
- // 验证码识别,传入图片路径。
- func (c OcrClient) GetCaptchaCodePath(ctx context.Context, imgPath string) (string, error) {
- bstr, err := base64Img(imgPath)
- if err != nil {
- return "", err
- }
- return c.GetCaptchaCode(ctx, bstr)
- }
- // 验证码识别,传入 "data:image/jpg;base64,xxx" 格式的 url。
- // 该 url 一般为 img 标签的 src 属性。不校验传入的 url 是否合法。
- func (c OcrClient) GetCaptchaCodeURL(ctx context.Context, b64 string) (string, error) {
- _, bstr, _ := strings.Cut(b64, ",")
- return c.GetCaptchaCode(ctx, bstr)
- }
- // 验证码识别,传入 base64 编码的图片。
- // 文档链接: https://www.chaojiying.com/price.html
- func (c OcrClient) GetCaptchaCode(ctx context.Context, bstr string) (string, error) {
- u, err := url.Parse(c.BaseURL)
- if err != nil {
- return "", err
- }
- u = u.JoinPath("/Upload/Processing.php")
- param := make(url.Values)
- param.Set("user", c.Option.User)
- param.Set("pass", c.Option.Pass)
- param.Set("softid", c.Option.SoftId)
- param.Set("codetype", "1902")
- param.Set("file_base64", bstr)
- params := param.Encode()
- req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), strings.NewReader(params))
- if err != nil {
- return "", err
- }
- req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
- resp, err := c.Client.Do(req)
- if err != nil {
- return "", err
- }
- defer resp.Body.Close()
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return "", err
- }
- var rs Result
- err = json.Unmarshal(body, &rs)
- if err != nil {
- return "", err
- }
- if rs.ErrNo != 0 {
- c.Logger.Error("识别报错", zap.ByteString("body", body))
- return "", err
- }
- c.Logger.Debug("识别结果", zap.String("picStr", rs.PicStr))
- return rs.PicStr, nil
- }
|