前言

最近比较了几家大的云平台产品,发现百度云的ocr识别,只要通过了企业认证的话,可以每天免费获取一定额度的使用,因此在这里分享下如何使用ocr识别api

目标

可用在实现内部员工系统的快速身份认证,或者部分客户的营业执照和个人认证,注意仅限小量内部使用,如需用在正式环境中建议购买足够的流量包

前置条件

开发环境 PHP 百度云能企业认证

正式内容

百度接口的认证方式

百度的鉴权方式是以Token的方式,具体教程可查看官网API,这里不重复说明了

function getToken

封装下获取Token的方式,避免重复请求次数过于频繁

public function getToken()
        {
            $filename = "/data/baidu_access_token.{$this->access_key}.json";
            if (file_exists($filename)) {
                $content = file_get_contents($filename);
                if ($content) {
                    $json = json_decode($content, 1);
                    if (strtotime($json['expires_in']) > time()) {
                        return $json['access_token'];
                    }
                }
            }
            $resp = json_decode($this->client->request("POST", "https://aip.baidubce.com/oauth/2.0/token", [
                'form_params' => [
                    'grant_type' => 'client_credentials',
                    'client_id' => $this->access_key,
                    'client_secret' => $this->secret_key,
                ]
            ])->getBody()->getContents(), 1);
            $data = [
                'access_token' => $resp['access_token'],
                'expires_in' => date("Y-m-d H:i:s", strtotime("+29 day")),
            ];
            file_put_contents($filename, json_encode($data, JSON_UNESCAPED_UNICODE));
            return $resp['access_token'];
        }

  
    
private function request($action, $p)
        {
            $option = [
                'query' => [
                    'access_token' => $this->getToken(),
                ],
            ];
            if ($this->target == 'face') {
                $option['json'] = $p;
            } else {
                $option['form_params'] = $p;
            }
            $resp = $this->client->request("POST", "{$api_url}/{$action}", $option)
                ->getBody()
                ->getContents();
            return json_decode($resp, true);
        }

身份证识别 function OcrIdcard

先展示官方文档,文档中可看出ocr的识别支持两种提交方式,图片的base64或者图片url,因此这里稍微封装一下

/**
         * 身份证识别
         * @param $id_card_side string 正反面 -front:身份证含照片的一面 -back:身份证带国徽的一面
         * @param string $image string 图像数据
         * @param string $url string 图片完整URL
         * @param array $param
         * @return mixed
         */
        public function OcrIdcard($id_card_side, $image = "", $url = "", $param = [])
        {
            $p = ['id_card_side' => $id_card_side];
            if ($image) {
                $p['image'] = $image;
            } elseif ($url) {
                $p['url'] = $url;
            }
            $redisValue = $this->redis->get("Ocr:Baidu:Idcard");
            $redisDate = $this->redis->get("Ocr:Baidu:IdcardDate");
            if (!$redisDate || $redisDate != date("Y-m-d")) {
                $this->redis->set("Ocr:Baidu:IdcardDate", date("Y-m-d"));
                $redisValue = 0;
            }
            if ($redisValue && $redisValue > 480) {
                return "api.count.limit";
            }
            $this->redis->set("Ocr:Baidu:Idcard", $redisValue ? $redisValue + 1 : 1);
            $resp = $this->request("/rest/2.0/ocr/v1/idcard", $p);
            if (isset($resp["error_msg"])) {
                return $resp["error_msg"];
            }
            $data = [
                'name' => isset($resp["words_result"]["姓名"])&&$resp["words_result"]["姓名"] ? $resp["words_result"]["姓名"]['words'] : "",
                'nation' => isset($resp["words_result"]["民族"])&&$resp["words_result"]["民族"] ? $resp["words_result"]["民族"]['words'] : "",
                'address' => isset($resp["words_result"]["住址"])&&$resp["words_result"]["住址"] ? $resp["words_result"]["住址"]['words'] : "",
                'idnumber' => isset($resp["words_result"]["公民身份号码"])&&$resp["words_result"]["公民身份号码"] ? $resp["words_result"]["公民身份号码"]['words'] : "",
                'birthday' => isset($resp["words_result"]["出生"])&&$resp["words_result"]["出生"] ? $resp["words_result"]["出生"]['words'] : "",
                'sex' => isset($resp["words_result"]["性别"])&&$resp["words_result"]["性别"] ? $resp["words_result"]["性别"]['words'] : "",
                'expired_at' => isset($resp["words_result"]["失效日期"])&&$resp["words_result"]["失效日期"] ? date("Y-m-d",strtotime($resp["words_result"]["失效日期"]['words'])) : "",
                'created_at' => isset($resp["words_result"]["签发日期"])&&$resp["words_result"]["签发日期"] ? date("Y-m-d",strtotime($resp["words_result"]["签发日期"]['words'])) : "",
            ];
            if (!$data['idnumber']&&!$data['expired_at']) return "idnumber.empty";
            return $data;
        }

可以看到这里使用了一段redis进行数量限制,百度每日可免费使用的额度是500次,避免测试中引起的差异,这里限制正式环境中每天可调用490次接口

营业执照识别 function OcrBusinessLicense

public function OcrBusinessLicense($image = "", $url = "", $param = [])
        {
            $p = [
            ];
            if ($image) {
                $p['image'] = $image;
            } elseif ($url) {
                $p['url'] = $url;
            }
            $redisValue = $this->redis->get("Ocr:Baidu:BusinessLicense");
            $redisDate = $this->redis->get("Ocr:Baidu:BusinessLicenseDate");
            if (!$redisDate || $redisDate != date("Y-m-d")) {
                $this->redis->set("Ocr:Baidu:BusinessLicenseDate", date("Y-m-d"));
                $redisValue = 0;
            }
            if ($redisValue && $redisValue > 190) {
                return "api.count.limit";
            }
            $this->redis->set("Ocr:Baidu:BusinessLicense", $redisValue ? $redisValue + 1 : 1);
            $resp = $this->request("/rest/2.0/ocr/v1/business_license", $p);
            if (isset($resp["error_msg"])) {
                return $resp["error_msg"];
            }
            $data = [
                'reg_num' => $resp["words_result"]["社会信用代码"] ? $resp["words_result"]["社会信用代码"]['words'] : "", //注册号
                'name' => $resp["words_result"]["单位名称"] ? $resp["words_result"]["单位名称"]['words'] : "", //公司名称
                'type' => $resp["words_result"]["类型"] ? $resp["words_result"]["类型"]['words'] : "", //公司类型
                'person' => $resp["words_result"]["法人"] ? $resp["words_result"]["法人"]['words'] : "", //公司法人
                'establish_date' => $resp["words_result"]["成立日期"] ? $resp["words_result"]["成立日期"]['words'] : "", //公司注册日期
                'valid_period' => $resp["words_result"]["有效期"] ? $resp["words_result"]["有效期"]['words'] : "", //公司营业期限终止日期
                'address' => $resp["words_result"]["地址"] ? $resp["words_result"]["地址"]['words'] : "", //公司地址
                'capital' => $resp["words_result"]["注册资本"] ? $resp["words_result"]["注册资本"]['words'] : "", //注册资本
                'business' => $resp["words_result"]["经营范围"] ? $resp["words_result"]["经营范围"]['words'] : "", //经营范围
            ];

            if (!$data['reg_num']) {
                return "reg_num.empty";
            }
            $data['establish_date'] = str_replace(["年", "月"], "-", $data['establish_date']);
            $data['establish_date'] = str_replace(["日"], "", $data['establish_date']);
            $data['valid_period'] = str_replace(["年", "月"], "-", $data['valid_period']);
            $data['valid_period'] = str_replace(["日"], "", $data['valid_period']);
            return $data;
        }