暂时未有相关云产品技术能力~
编程制作上一直都不是一帆风顺的,比如今天小编就遇到了一个问题,缺少module,常见的方式,一定是想到第三方模块,使用pip命令进行安装即可,大部分的时候都是可以实现的,但是有些时候,我们需要利用其它方式才可以进行解决,下面就给大家带来解决缺少module的方法办法。缺少module显示:import requests from bs4 import BeautifulSoup import os解决方法:1、利用pip安装缺失的库2、打开cmd命令,进入安装目录cd C:\Coding\Python36\Scripts3、执行命令安装缺失的库C:\Coding\Python36\Scripts>pip.exe install requests
注意:微信小程序红包功能一定记得用企业付款到钱包功能,别用微信的现金红包接口,否则你就有踩不完的坑。这里我就直接上代码了微信小程序代码:index.js//抢红包相关 view_moneysure: function () { var that = this; wx.request({ url: app.globalData.baseurl +'api/wxopen/applet/grab',//这个链接是后端写的 header: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: { openid: app.globalData.openid, auth: app.globalData.pcUserInfo.auth }, method: 'POST', success: function (response) { console.log(response); if (response.data.status==1){ that.setData({ paymsg: response.data.total_amount+'元\n现金红包', paymsg2: '恭喜您\n成功领取下单红包奖励' }) }else{ that.setData({ paymsg: '领取失败\n'+response.data.msg, paymsg2: '非常抱歉\n如不不明,请联系客服' }) } }, fail: function (res) { console.log(response); that.setData({ paymsg: '领取失败' }) } }) }, showHb: function () { this.setData({ showFlag: 1 }) }, openHb: function () { this.setData({ paymsg: '', paymsg2: '' }) this.view_moneysure() var _self = this; _self.setData({ _num: 1 }) setTimeout(function () { _self.setData({ _num: 0, showFlag: 0, bghide: 1 }) }, 1000) }, closeHb:function(){ this.setData({ bghide:0 }) }, wxml代码:<button class="btn" bindtap="showHb">领红包</button> <view class="draw-list {{showFlag == 1? 'active':''}}"> <image bindtap="openHb" class="{{_num==1?'active':''}}" src="http://www.17sucai.com/preview/1/2017-11-02/hb/image/open.png"></image> </view> <view id="receive1" class="win1 {{bghide==1?'active':''}}"> <view class="openhb {{bghide==1?'active':''}}"> <view class="winBody2"> <view class="receive1-bg1"> <view class="receive1-head"> <text>{{paymsg}}</text> </view> <view class="receive1-body"><text>{{paymsg2}}</text></view> <button class="receive1-but1" bindtap="closeHb">确定</button> <view class="receive1-bg2"></view> </view> </view> </view> </view>PHP代码:/* * 企业付款到零钱 **/ public function weixin_pay_person($re_openid) { $obj = new WxopenWechatService(); // 请求参数 $data['mch_appid'] = WxopenWechatConfig::$init_config_applet['appid'];//商户号 $data['mchid'] = WxopenWechatConfig::$compay_config['mch_id'];//商户账号appid $data['nonce_str'] = $this->get_unique_value();// 随机字符串 //商户订单号,可以按要求自己组合28位的商户订单号 $data['partner_trade_no'] = $this->get_tradeno($data['mchid']); $data['openid'] = $re_openid;//用户openid $data['check_name'] = 'NO_CHECK';//校验用户姓名选项 $data['amount'] = '100';//金额,单位为分 $data['desc'] = "恭喜你得到一个红包";//企业付款描述信息 $data['spbill_create_ip'] = $obj->get_client_ip();//IP地址 $appsecret = WxopenWechatConfig::$compay_config['key']; $data['sign'] = $this->sign($data, $appsecret); //发红包接口地址 $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; //将请求数据由数组转换成xml $xml = $this->arraytoxml($data); //进行请求操作 $res = $this->curl($xml, $url); //将请求结果由xml转换成数组 $arr = $this->xmltoarray($res); if (is_array($arr)) { $arr['total_amount'] = $data['amount']; } //请请求信息和请求结果录入到数据库中 // 输出请求结果数组 return $arr; } public function create_rand_money($start = 30, $end = 100) { return mt_rand($start, $end); } public function sign($params, $appsecret) { ksort($params); $beSign = array_filter($params, 'strlen'); $pairs = array(); foreach ($beSign as $k => $v) { $pairs[] = "$k=$v"; } $sign_data = implode('&', $pairs); $sign_data .= '&key=' . $appsecret; return strtoupper(md5($sign_data)); } /* * 生成32位唯一随机字符串 **/ private function get_unique_value() { $str = uniqid(mt_rand(), 1); $str = sha1($str); return md5($str); } /* * 将数组转换成xml **/ private function arraytoxml( $arr ) { $xml = "<xml>"; foreach ($arr as $k => $v) { $xml .= "<" . $k . ">" . $v . "</" . $k . ">"; } $xml .= "</xml>"; return $xml; } /* * 将xml转换成数组 **/ private function xmltoarray( $xml ) { //禁止引用外部xml实体 libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA); $arr = json_decode(json_encode($xmlstring), true); return $arr; } /* * 进行curl操作 **/ private function curl( $param = "", $url ) { $postUrl = $url; $curlPost = $param; //初始化curl $ch = curl_init(); //抓取指定网页 curl_setopt($ch, CURLOPT_URL, $postUrl); //设置header curl_setopt($ch, CURLOPT_HEADER, 0); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //post提交方式 curl_setopt($ch, CURLOPT_POST, 1); // 增加 HTTP Header(头)里的字段 curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 终止从服务端进行验证 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //这个是证书的位置 curl_setopt($ch, CURLOPT_SSLCERT, __DIR__ . '/cert/apiclient_cert.pem'); //这个也是证书的位置 curl_setopt($ch, CURLOPT_SSLKEY, __DIR__ . '/cert/apiclient_key.pem'); //运行curl $data = curl_exec($ch); //关闭curl curl_close($ch); return $data; } public function get_tradeno($str) { return $str . date("Ymd", time()) . date("His", time()) . rand(1111, 9999); }别人总结的相当宝贵的踩坑经验:1、红包是以分为单位,必须大于100分,小于20000分之间。2、用户无需关注你的公众号(或服务号,下同),如果关注了你的公众号,红包会通过公众号发送,如果没有,通过服务通知发送。3、接口中的订单号由“微信支付商户号+4位年+2为月份+2位日期+10位一天内不能重复的数字”,这个一天是自然日。4、目前不支持发送随机红包,因此接口中提交的字段min_value、max_value、total_amount这3个值大小必须一样,total_num值必须为1.5、随机红包可以自己的程序实现,在100~20000随机出一个数值,然后给上面3个值设定这个随机结果。6、活动名称看起来没用,注意高级红包接口和商户平台现金红包中的管理红包和创建红包无关,这两个地方是给手工发送红包使用的。7、可选的4个参数,目前看来都没用,不要传。logo_imgurl, share_content, share_url, share_imgurl。8、签名注意,值为空的不要参与签名。最后附加的key是微信支付的API密钥,不是公众平台的密钥,在商户平台->账户设置->安全设置->API安全右下角设置密钥中设置,第一次使用微信支付需要设置。9、中文不需要UrlEncode,Hash输入是byte数组,用Encoding.UTF8.GetBytes来获取。10、证书强烈建议不采用微信官方Demo文件访问形式证书,应该安装在系统证书存储容器中(在命令行输入certmgr可以查看),并设置为私钥不可以导出。11、如果你采用10的方式,你很容易遇到无法找到证书的问题,要求运行程序windows账号有访问这个证书的权限。比如,如果双击运行的控制台程序,证书安装在当前用户的个人类别中,那么程序就可以访问证书。如果是IIS账户,你可能需要指定应用程序池的执行账号为指定账号,然后这个证书安装在这个账号下。微信官方Demo采用文件的访问形式,就不会有权限问题,但是要求你对证书文件保管好,以及证书密钥保管好。通过以上的简略步骤相信功能以及实现的差不多了:学习小程序做好的方式除了看文档就是,模仿.以上就是本文的全部内容,希望对大家的学习有所帮助.
有时候我们可能需要在其他的网页上展示我们自己的小程序中某些页面的小程序码,这种时候,我们需要用到小程序的生成小程序码的相关接口。工具选型我们仍然选用简单方便的weixin-java-miniapp来完成此功能。生成小程序码的相关类型小程序码的其他生成方式以及相关类型在这篇文章点此进入中介绍的较为详细,此处不再赘述,以下仅以生成不限制张数的这种类型来做一个示例。生成小程序码图片先获取小程序的service实例wxMaService。再获取二维码相关操作的service实例// 获取小程序服务实例 WxMaService wxMaService = WxMaConfiguration.getWxMaService(); // 获取小程序二维码生成实例 WxMaQrcodeService wxMaQrcodeService = wxMaService.getQrcodeService(); // 设置小程序二维码线条颜色为黑色 WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); // 生成二维码图片字节流(此处也可以生成File类型,如果想将图片文件保存到服务器就生成File类型,此处生成byte[]类型,方便直接返回文件流到前端) byte[] qrCodeBytes = null; qrCodeBytes = wxMaQrcodeService.createWxaCodeUnlimitBytes(String.valueOf(id), null, 430, false, lineColor, false);返回文件流将文件流写到response中,相关示例代码如下:@RestController @RequestMapping("/qrCode") public class QrCodeController { private static final Logger logger = LoggerFactory.getLogger(QrCodeController.class); @GetMapping("/getMiniappQrCode/{id}") public void getMiniappQrCode(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws Exception{ // 获取小程序服务实例 WxMaService wxMaService = WxMaConfiguration.getWxMaService(); // 获取小程序二维码生成实例 WxMaQrcodeService wxMaQrcodeService = wxMaService.getQrcodeService(); // 设置小程序二维码线条颜色为黑色 WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); // 生成二维码图片字节流 byte[] qrCodeBytes = null; try{ qrCodeBytes = wxMaQrcodeService.createWxaCodeUnlimitBytes(String.valueOf(id), null, 430, false, lineColor, false); } catch(Exception e){ logger.error("生成小程序码出错", e); } // 设置contentType response.setContentType("image/png"); // 写入response的输出流中 OutputStream stream = response.getOutputStream(); stream.write(qrCodeBytes); stream.flush(); stream.close(); } }
表格的一些样式<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>My Test bootstrap</title> <link rel="stylesheet" href="./css/bootstrap.min.css"> <script type="text/javascript" src="./js/bootstrap.min.js"></script> </head> <body> <table class="table table-striped"> <caption>这是一个测试表格</caption> <thead> <tr> <th>姓名</th> <th>年龄</th> <th>地区</th> </tr> </thead> <tbody> <tr> <td>小胡子</td> <td>26</td> <td>陕西</td> </tr> <tr> <td>大胡子</td> <td>26</td> <td>北京</td> </tr> </tbody> </table> </body> </html>界面效果表格行或单元格的样式<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>My Test bootstrap</title> <link rel="stylesheet" href="./css/bootstrap.min.css"> <script type="text/javascript" src="./js/bootstrap.min.js"></script> </head> <body> <table class="table table-striped"> <caption>这是一个测试表格</caption> <thead> <tr> <th>姓名</th> <th>年龄</th> <th>地区</th> </tr> </thead> <tbody> <tr class="info"> <td>小胡子</td> <td>26</td> <td>陕西</td> </tr> <tr class="warning"> <td>大胡子</td> <td>26</td> <td>北京</td> </tr> </tbody> </table> </body> </html>界面效果表单布局垂直表单<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>My Test bootstrap</title> <link rel="stylesheet" href="./css/bootstrap.min.css"> <script type="text/javascript" src="./js/bootstrap.min.js"></script> </head> <body> <form role="form"> <div class="form-group"> <label for="name">姓名</label> <input type="text" class="form-control" id="name" placeholder="请输入姓名"> </div> <div class="form-group"> <label for="inputfile">选择文件</label> <input type="file" id="inputfile"> </div> <button type="submit" class="btn btn-default">提交</button> </form> </body> </html>内联表单:它的所有元素是内联的,向左对齐的,标签是并排的<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>My Test bootstrap</title> <link rel="stylesheet" href="./css/bootstrap.min.css"> <script type="text/javascript" src="./js/bootstrap.min.js"></script> </head> <body> <form role="form" class="form-inline"> <div class="form-group"> <label for="name">姓名</label> <input type="text" class="form-control" id="name" placeholder="请输入姓名"> </div> <div class="form-group"> <label for="inputfile">选择文件</label> <input type="file" id="inputfile"> </div> <button type="submit" class="btn btn-default">提交</button> </form> </body> </html>水平表单:水平表单与其他表单不仅标记的数量上不同,而且表单的呈现形式也不同<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>My Test bootstrap</title> <link rel="stylesheet" href="./css/bootstrap.min.css"> <script type="text/javascript" src="./js/bootstrap.min.js"></script> </head> <body> <form role="form" class="form-horizontal"> <div class="form-group"> <label for="name" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="name" placeholder="请输入姓名"> </div> </div> <div class="form-group"> <label for="inputfile" class="col-sm-2 control-label">选择文件</label> <div class="col-sm-10"> <input type="file" id="inputfile"> <div> </div> <div class="form-group"> <div class="col-sm-12"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </body> </html>
最近开发了一个拍车牌识别车牌号的功能,主要调用了腾讯的ocr车牌识别接口。首先,生成签名以及读取配置的工具类: package com.weaver.formmodel.integration.ocr; import java.util.Random; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import weaver.general.Base64; public class SignUtil { /** * 生成 Authorization 签名字段 * * @param appId * @param secretId * @param secretKey * @param bucketName * @param expired * @return 签名字符串 * @throws Exception */ public static String appSign(long appId, String secretId, String secretKey, String bucketName, long expired) throws Exception { long now = System.currentTimeMillis() / 1000; int rdm = Math.abs(new Random().nextInt()); String plainText = String.format("a=%d&b=%s&k=%s&t=%d&e=%d&r=%d", appId, bucketName, secretId, now, now + expired, rdm); byte[] hmacDigest = HmacSha1(plainText, secretKey); byte[] signContent = new byte[hmacDigest.length + plainText.getBytes().length]; System.arraycopy(hmacDigest, 0, signContent, 0, hmacDigest.length); System.arraycopy(plainText.getBytes(), 0, signContent, hmacDigest.length, plainText.getBytes().length); return Base64Encode(signContent); } /** * 生成 base64 编码 * * @param binaryData * @return */ public static String Base64Encode(byte[] binaryData) { String encodedstr = new String(Base64.encode(binaryData)); return encodedstr; } /** * 生成 hmacsha1 签名 * * @param binaryData * @param key * @return * @throws Exception */ public static byte[] HmacSha1(byte[] binaryData, String key) throws Exception { Mac mac = Mac.getInstance("HmacSHA1"); SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1"); mac.init(secretKey); byte[] HmacSha1Digest = mac.doFinal(binaryData); return HmacSha1Digest; } /** * 生成 hmacsha1 签名 * * @param plainText * @param key * @return * @throws Exception */ public static byte[] HmacSha1(String plainText, String key) throws Exception { return HmacSha1(plainText.getBytes(), key); } }package weaver.general; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; /** * Provides encoding of raw bytes to base64-encoded characters, and decoding of * base64 characters to raw bytes. date: 06 August 1998 modified: 14 February * 2000 modified: 22 September 2000 * * @author Kevin Kelley (kelley@ruralnet.net) * @version 1.3 */ public class Base64 { /** * returns an array of base64-encoded characters to represent the passed * data array. * * @param data * the array of bytes to encode * @return base64-coded character array. */ public static char[] encode(byte[] data) { char[] out = new char[((data.length + 2) / 3) * 4]; // // 3 bytes encode to 4 chars. Output is always an even // multiple of 4 characters. // for (int i = 0, index = 0; i < data.length; i += 3, index += 4) { boolean quad = false; boolean trip = false; int val = (0xFF & data[i]); val <<= 8; if ((i + 1) < data.length) { val |= (0xFF & data[i + 1]); trip = true; } val <<= 8; if ((i + 2) < data.length) { val |= (0xFF & data[i + 2]); quad = true; } out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)]; val >>= 6; out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)]; val >>= 6; out[index + 1] = alphabet[val & 0x3F]; val >>= 6; out[index + 0] = alphabet[val & 0x3F]; } return out; } /** * Decodes a BASE-64 encoded stream to recover the original data. White * space before and after will be trimmed away, but no other manipulation of * the input will be performed. * * As of version 1.2 this method will properly handle input containing junk * characters (newlines and the like) rather than throwing an error. It does * this by pre-parsing the input and generating from that a count of VALID * input characters. **/ public static byte[] decode(char[] data) { // as our input could contain non-BASE64 data (newlines, // whitespace of any sort, whatever) we must first adjust // our count of USABLE data so that... // (a) we don't misallocate the output array, and // (b) think that we miscalculated our data length // just because of extraneous throw-away junk int tempLen = data.length; for (int ix = 0; ix < data.length; ix++) { if ((data[ix] > 255) || codes[data[ix]] < 0) --tempLen; // ignore non-valid chars and padding } // calculate required length: // -- 3 bytes for every 4 valid base64 chars // -- plus 2 bytes if there are 3 extra base64 chars, // or plus 1 byte if there are 2 extra. int len = (tempLen / 4) * 3; if ((tempLen % 4) == 3) len += 2; if ((tempLen % 4) == 2) len += 1; byte[] out = new byte[len]; int shift = 0; // # of excess bits stored in accum int accum = 0; // excess bits int index = 0; // we now go through the entire array (NOT using the 'tempLen' value) for (int ix = 0; ix < data.length; ix++) { int value = (data[ix] > 255) ? -1 : codes[data[ix]]; if (value >= 0)// skip over non-code { accum <<= 6; // bits shift up by 6 each time thru shift += 6; // loop, with new bits being put in accum |= value; // at the bottom. if (shift >= 8)// whenever there are 8 or more shifted in, { shift -= 8; // write them out (from the top, leaving any out[index++] = // excess at the bottom for next iteration. (byte) ((accum >> shift) & 0xff); } } // we will also have skipped processing a padding null byte ('=') // here; // these are used ONLY for padding to an even length and do not // legally // occur as encoded data. for this reason we can ignore the fact // that // no index++ operation occurs in that special case: the out[] array // is // initialized to all-zero bytes to start with and that works to our // advantage in this combination. } // if there is STILL something wrong we just have to throw up now! if (index != out.length) { throw new Error("Miscalculated data length (wrote " + index + " instead of " + out.length + ")"); } return out; } // // code characters for values 0..63 // private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" .toCharArray(); // // lookup table for converting base64 characters to value in range 0..63 // private static byte[] codes = new byte[256]; static { for (int i = 0; i < 256; i++) codes[i] = -1; for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte) (i - 'A'); for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte) (26 + i - 'a'); for (int i = '0'; i <= '9'; i++) codes[i] = (byte) (52 + i - '0'); codes['+'] = 62; codes['/'] = 63; } // ///////////////////////////////////////////////// // remainder (main method and helper functions) is // for testing purposes only, feel free to clip it. // ///////////////////////////////////////////////// public static void main(String[] args) { boolean decode = false; if (args.length == 0) { System.out.println("usage: java Base64 [-d[ecode]] filename"); System.exit(0); } for (int i = 0; i < args.length; i++) { if ("-decode".equalsIgnoreCase(args[i])) decode = true; else if ("-d".equalsIgnoreCase(args[i])) decode = true; } String filename = args[args.length - 1]; File file = new File(filename); if (!file.exists()) { System.out .println("Error: file '" + filename + "' doesn't exist!"); System.exit(0); } if (decode) { char[] encoded = readChars(file); byte[] decoded = decode(encoded); writeBytes(file, decoded); } else { byte[] decoded = readBytes(file); char[] encoded = encode(decoded); writeChars(file, encoded); } } private static byte[] readBytes(File file) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { InputStream fis = new FileInputStream(file); InputStream is = new BufferedInputStream(fis); int count = 0; byte[] buf = new byte[16384]; while ((count = is.read(buf)) != -1) { if (count > 0) baos.write(buf, 0, count); } is.close(); } catch (Exception e) { e.printStackTrace(); } return baos.toByteArray(); } private static char[] readChars(File file) { CharArrayWriter caw = new CharArrayWriter(); try { Reader fr = new FileReader(file); Reader in = new BufferedReader(fr); int count = 0; char[] buf = new char[16384]; while ((count = in.read(buf)) != -1) { if (count > 0) caw.write(buf, 0, count); } in.close(); } catch (Exception e) { e.printStackTrace(); } return caw.toCharArray(); } private static void writeBytes(File file, byte[] data) { try { OutputStream fos = new FileOutputStream(file); OutputStream os = new BufferedOutputStream(fos); os.write(data); os.close(); } catch (Exception e) { e.printStackTrace(); } } private static void writeChars(File file, char[] data) { try { Writer fos = new FileWriter(file); Writer os = new BufferedWriter(fos); os.write(data); os.close(); } catch (Exception e) { e.printStackTrace(); } } // ///////////////////////////////////////////////// // end of test code. // ///////////////////////////////////////////////// }package weaver.general; import java.io.File; import java.io.FileInputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; public class BaseBean { private static Map<String, Properties> propertyMap = new HashMap<String, Properties>(); public String getPropValue(String cONFIG_FILE, String key) { if (propertyMap.get(cONFIG_FILE) == null) { readPro(cONFIG_FILE); } Properties pro = propertyMap.get(cONFIG_FILE); return pro.getProperty(key); } private void readPro(String cONFIG_FILE) { Properties pro = new Properties(); FileInputStream in; try { String path = Thread.currentThread().getContextClassLoader() .getResource("").toString(); path = path.substring(6, path.indexOf("classes/")); path = path + "prop/" + cONFIG_FILE + ".properties"; path = path.replace("%20", " "); System.out.println(path); File f = new File(path); if (!f.exists()) { throw new RuntimeException("要读取的文件不存在"); } in = new FileInputStream(f); pro.load(in); in.close(); propertyMap.put(cONFIG_FILE, pro); } catch (Exception e) { e.printStackTrace(); } } }package weaver.general; public class Util { public static int getIntValue(String value) { try { return Integer.parseInt(value); } catch (NumberFormatException e) { e.printStackTrace(); return 0; } } }然后是接口调配置文件:重点来了,调用接口部分:package com.weaver.formmodel.integration.ocr; import java.util.HashMap; import java.util.Map; import net.sf.json.JSONObject; import org.apache.commons.httpclient.HttpStatus; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.util.EntityUtils; import weaver.general.BaseBean; import weaver.general.Util; public class OCRClient{ private static String CONFIG_FILE = "OCR_Tencent"; private static String host; private static int appid; private static String secretId; private static String secretKey; private static String targeturl; private static String encoding = "UTF-8"; static { BaseBean bb = new BaseBean(); host = bb.getPropValue(CONFIG_FILE, "host"); appid = Util.getIntValue(bb.getPropValue(CONFIG_FILE, "appid")); secretId = bb.getPropValue(CONFIG_FILE, "secretId"); secretKey = bb.getPropValue(CONFIG_FILE, "secretKey"); targeturl = bb.getPropValue(CONFIG_FILE, "targetUrl"); } /** * 识别图片 * @param imageurl * @param paramsMap 参数map * @return * @throws Exception */ public static Map<String, Object> recognizeImage(Map<String,Object> paramsMap) throws Exception{ HttpClient httpclient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(targeturl);// 创建httpPost httpPost.setHeader("host", host); //设置签名 httpPost.setHeader("Authorization", SignUtil.appSign(appid, secretId, secretKey, "", 2592000));//设置请求头, 签名 //设置参数 JSONObject requestParam = new JSONObject(); requestParam.put("appid", String.valueOf(appid)); for(String key :paramsMap.keySet()){//循环加入请求参数 requestParam.put(key, paramsMap.get(key)); } //请求报文 StringEntity entity = new StringEntity(requestParam.toString(), encoding); entity.setContentEncoding(encoding); entity.setContentType("application/json");//发送json数据需要设置contentType httpPost.setEntity(entity); httpPost.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 120000); httpPost.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 120000); int state = 0; String result = ""; HttpResponse response = null; try { response = httpclient.execute(httpPost); StatusLine status = response.getStatusLine(); state = status.getStatusCode(); if (state == HttpStatus.SC_OK) { HttpEntity responseEntity = response.getEntity(); result = EntityUtils.toString(responseEntity); }else{ //new BaseBean().writeLog("读取OCR驾驶证或者行驶证接口失败,状态码:"+state); } } finally { httpclient.getConnectionManager().shutdown(); } Map<String, Object> resultMap = new HashMap<String, Object>(); resultMap.put("state", state); resultMap.put("result", result); return resultMap; } //测试 public static void main(String[] args) { String imgurl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1532414063478&di=f8709d73023a1a4ef9fe58f23ec95a8e&imgtype=jpg&src=http%3A%2F%2Fimg3.imgtn.bdimg.com%2Fit%2Fu%3D2587099383%2C4041264664%26fm%3D214%26gp%3D0.jpg"; try { //车牌号识别参数设置 Map<String, Object> requestParam = new HashMap<String, Object>(); requestParam.put("url", imgurl); Map<String,Object> res =recognizeImage(requestParam); //解析车牌号返回值 JSONObject resultJson = JSONObject.fromObject(res.get("result")); System.out.println(resultJson.toString()); } catch (Exception e) { e.printStackTrace(); } } }如果大家需调用其他接口,如身份证识别接口、驾驶证识别接口等;只需要修改一下配置文件的targeturl,并且调用时传入相应的参数即可。
整理文档时,搜刮出一个Java实现身份证号码验证源码示例代码,稍微整理精简了一下分享给大家。 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Random; /** * 身份证验证的工具(支持15位或18位省份证) * 身份证号码结构: * <p> * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。 * 排列顺序从左至右依次为:6位数字地址码,8位数字出生日期码,3位数字顺序码和1位数字校验码。 * <p> * 地址码(前6位):表示对象常住户口所在县(市、镇、区)的行政区划代码,按GB/T2260的规定执行。 * <li>前1、2位数字表示:所在省份的代码;</li> * <li>第3、4位数字表示:所在城市的代码;</li> * <li>第5、6位数字表示:所在区县的代码;</li> * <p> * 出生日期码,(第7位 - 14位):表示编码对象出生年、月、日,按GB按GB/T7408的规定执行,年、月、日代码之间不用分隔符。 * <p> * 顺序码(第15位至17位):表示在同一地址码所标示的区域范围内,对同年、同月、同日出生的人编订的顺序号,顺序码的奇数分配给男性,偶数分配给女性。 * <li>第15、16位数字表示:所在地的派出所的代码;</li> * <li>第17位数字表示性别:奇数表示男性,偶数表示女性;</li> * <li>第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。</li> * <p> * 校验码(第18位数): * <p> * 十七位数字本体码加权求和公式 s = sum(Ai*Wi), i = 0..16,先对前17位数字的权求和; * Ai:表示第i位置上的身份证号码数字值.Wi:表示第i位置上的加权因子.Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2; * 计算模 Y = mod(S, 11) * 通过模得到对应的模 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2 * <p> * 计算步骤: * 1.将前17位数分别乘以不同的系数。从第1位到第17位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 * 2.将这17位数字和系数相乘的结果相加。 * 3.用加出来和除以11,看余数是多少 * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字,分别对应的最后一位身份证的号码为:1 0 X 9 8 7 6 5 4 3 * <p> * 我的Java学习交流QQ群:589809992 我们一起学Java! */ public class IDCardUtil { /** * <pre> * 省、直辖市代码表: * 11 : 北京 12 : 天津 13 : 河北 14 : 山西 15 : 内蒙古 * 21 : 辽宁 22 : 吉林 23 : 黑龙江 31 : 上海 32 : 江苏 * 33 : 浙江 34 : 安徽 35 : 福建 36 : 江西 37 : 山东 * 41 : 河南 42 : 湖北 43 : 湖南 44 : 广东 45 : 广西 46 : 海南 * 50 : 重庆 51 : 四川 52 : 贵州 53 : 云南 54 : 西藏 * 61 : 陕西 62 : 甘肃 63 : 青海 64 : 宁夏 65 : 新疆 * 71 : 台湾 * 81 : 香港 82 : 澳门 * 91 : 国外 * </pre> */ final static String CITY_CODE[] = {"11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", "81", "82", "91"}; /** * 效验码 */ final static char[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; /** * 加权因子 * Math.pow(2, i - 1) % 11 */ final static int[] POWER = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; /** * 身份证验证 * * @param id 号码内容 * @return 是否有效 */ public final static boolean isValid(String id) { if (id == null) return false; int len = id.length(); if (len != 15 && len != 18) return false; //校验区位码 if (!validCityCode(id.substring(0, 2))) return false; //校验生日 if (!validDate(id)) return false; if (len == 15) return true; //校验位数 return validParityBit(id); } private static boolean validParityBit(String id) { char[] cs = id.toUpperCase().toCharArray(); int power = 0; for (int i = 0; i < cs.length; i++) { //最后一位可以是X if (i == cs.length - 1 && cs[i] == 'X') break; // 非数字 if (cs[i] < '0' || cs[i] > '9') return false; // 加权求和 if (i < cs.length - 1) { power += (cs[i] - '0') * POWER[i]; } } return PARITYBIT[power % 11] == cs[cs.length - 1]; } private static boolean validDate(String id) { try { String birth = id.length() == 15 ? "19" + id.substring(6, 12) : id.substring(6, 14); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Date birthDate = sdf.parse(birth); if (!birth.equals(sdf.format(birthDate))) return false; } catch (ParseException e) { return false; } return true; } private static boolean validCityCode(String cityCode) { for (String code : CITY_CODE) { if (code.equals(cityCode)) return true; } return false; } /** * 将15位的身份证转成18位身份证 * * @param id * @return */ final public static String id15To18(String id) { if (id == null || id.length() != 15) return null; if (!isValid(id)) return null; String id17 = id.substring(0, 6) + "19" + id.substring(6); int power = 0; char[] cs = id17.toCharArray(); for (int i = 0; i < cs.length; i++) { power += (cs[i] - '0') * POWER[i]; } // 将前17位与第18位校验码拼接 return id17 + String.valueOf(PARITYBIT[power % 11]); } /** * 生成随机整数 * <p> * * @param min * @param max * @return */ public static int rand(int min, int max) { Random random = new Random(); return random.nextInt(max + 1) % (max - min + 1) + min; } public final static String generateID() { // 地址码 String body = CITY_CODE[rand(0, CITY_CODE.length - 1)] + "0101"; // 出生年 String y = String.valueOf(rand(1950, Calendar.getInstance().get(Calendar.YEAR))); String m = String.valueOf(rand(1, 12)); if (m.length() == 1) m = "0" + m; String d = String.valueOf(rand(1, 28)); if (d.length() == 1) d = "0" + d; String idx = String.valueOf(rand(1, 999)); if (idx.length() == 1) idx = "00" + idx; else if (idx.length() == 2) idx = "0" + idx; body += y + m + d + idx; // 累加body部分与位置加权的积 int power = 0; char[] cs = body.toCharArray(); for (int i = 0; i < cs.length; i++) { power += (cs[i] - '0') * POWER[i]; } // 得出校验码 return body + String.valueOf(PARITYBIT[power % 11]); } }
Python实现FTP上传文件或文件夹实例import sys import os import json from ftplib import FTP _XFER_FILE = 'FILE' _XFER_DIR = 'DIR' class Xfer(object): ''''' @note: upload local file or dirs recursively to ftp server ''' def __init__(self): self.ftp = None def __del__(self): pass def setFtpParams(self, ip, uname, pwd, port = 21, timeout = 60): self.ip = ip self.uname = uname self.pwd = pwd self.port = port self.timeout = timeout def initEnv(self): if self.ftp is None: self.ftp = FTP() print '### connect ftp server: %s ...'%self.ip self.ftp.connect(self.ip, self.port, self.timeout) self.ftp.login(self.uname, self.pwd) print self.ftp.getwelcome() def clearEnv(self): if self.ftp: self.ftp.close() print '### disconnect ftp server: %s!'%self.ip self.ftp = None def uploadDir(self, localdir='./', remotedir='./'): if not os.path.isdir(localdir): return self.ftp.cwd(remotedir) for file in os.listdir(localdir): src = os.path.join(localdir, file) if os.path.isfile(src): self.uploadFile(src, file) elif os.path.isdir(src): try: self.ftp.mkd(file) except: sys.stderr.write('the dir is exists %s'%file) self.uploadDir(src, file) self.ftp.cwd('..') def uploadFile(self, localpath, remotepath='./'): if not os.path.isfile(localpath): return print '+++ upload %s to %s:%s'%(localpath, self.ip, remotepath) self.ftp.storbinary('STOR ' + remotepath, open(localpath, 'rb')) def __filetype(self, src): if os.path.isfile(src): index = src.rfind('\\') if index == -1: index = src.rfind('/') return _XFER_FILE, src[index+1:] elif os.path.isdir(src): return _XFER_DIR, '' def upload(self, src): filetype, filename = self.__filetype(src) self.initEnv() if filetype == _XFER_DIR: self.srcDir = src self.uploadDir(self.srcDir) elif filetype == _XFER_FILE: self.uploadFile(src, filename) self.clearEnv() if __name__ == '__main__': srcDir = r"C:\sytst" srcFile = r'C:\sytst\sar.c' xfer = Xfer() xfer.setFtpParams('192.x.x.x', 'jenkins', 'pass') xfer.upload(srcDir) xfer.upload(srcFile)
今天碰到一个很有意思的问题,需要将普通的 Unicode字符串转换为 Unicode编码的字符串,如下:将 \u9500\u552e 转化为 \u9500\u552e 也就是销售两个字。乍一看感觉挺简单的,用 re 库将前面的反斜杠去掉即可,但是在替换的过程中会抛出如下错误:Traceback (most recent call last): File "<pyshell#15>", line 1, in re.sub(r"(\)\u", r'', t)File "D:\Python36\lib\re.py", line 191, in subreturn _compile(pattern, flags).sub(repl, string, count)File "D:\Python36\lib\re.py", line 301, in _compilep = sre_compile.compile(pattern, flags)File "D:\Python36\lib\sre_compile.py", line 562, in compilep = sre_parse.parse(p, flags)File "D:\Python36\lib\sre_parse.py", line 855, in parsep = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)File "D:\Python36\lib\sre_parse.py", line 416, in _parse_subnot nested and not items))File "D:\Python36\lib\sre_parse.py", line 765, in _parsep = _parse_sub(source, state, sub_verbose, nested + 1)File "D:\Python36\lib\sre_parse.py", line 416, in _parse_subnot nested and not items))File "D:\Python36\lib\sre_parse.py", line 502, in _parsecode = _escape(source, this, state)File "D:\Python36\lib\sre_parse.py", line 362, in _escaperaise source.error("incomplete escape %s" % escape, len(escape))sre_constants.error: incomplete escape \u at position 3大概意思就是去掉前面的反写杠之后剩下的 \u 不能组成完整的字符。到这里问题好像有点难以解决了,这时候我们会放弃吗?当然不会。于是我到谷歌上搜了一下,发现还真有人碰到过这个问题,解决方法也是十分的巧妙。竟然还可以使用 json 库的 loads 方法 ...解决方法如下:import json s = '\\u9500\\u552e' print(json.loads(f'"{s}"'))另外:python3 将字符串unicode转换为中文得到的文本打印出来是“\uxxxx”的字符串格式,在python3中使用text.decode('unicode_escape')会报错:‘str' object has no attribute 'decode'正确的姿势是:text.encode('utf-8').decode("unicode_escape")还有一个就是在爬取网站时,最终得到的是list内容,编码为unicode,想让其转换为汉字并输出。需要提取的为下图中unicode部分:保存为列表,然后使用for循环:text为获取的网页。pat = '"group": {"text": "(.*?)"' text_list = re.compile(pat).findall(text) for i in text_list: print(i.encode('latin-1').decode('unicode_escape'))输出结果:
2022年12月
2022年11月
2022年10月
2022年09月