Python的Bottle框架中使用微信API的示例

合集下载

python wechaty 的用法

python wechaty 的用法

Python Wechaty 的用法概述1. Python Wechaty 是一个利用技术实现信信智能机器人功能的开源项目。

它基于信信的网页版协议开发,可以让开发者通过 Python 语言轻松实现信信机器人的功能。

2. 本文将重点介绍 Python Wechaty 的用法和基本功能,帮助读者了解该项目的特点和使用方式。

Python Wechaty 的基本介绍3. Python Wechaty 是一款基于信信网页版协议的开源项目,主要用于实现信信智能机器人的功能。

4. Python Wechaty 支持大部分基本的信信功能,包括文本消息、语音消息、图片消息以及裙聊功能等。

5. 通过 Python Wechaty,开发者可以将信信智能机器人应用于自动回复、消息转发、信息推送等各种场景。

6. Python Wechaty 提供了丰富的API接口和插件机制,开发者可以根据自己的需求灵活扩展和定制功能。

7. Python Wechaty 采用了现代化的异步编程模式,能够高效地处理大量的并发请求,保证了信信机器人的稳定性和性能。

Python Wechaty 的使用方法8. 开发者可以通过 Python 的包管理工具 pip 来安装 PythonWechaty,只需要简单的命令就可以完成安装。

9. 安装完成后,开发者可以通过导入 Wechaty 的模块来开始编写自己的信信机器人程序。

10. 在编写程序的过程中,开发者可以利用 Wechaty 提供的丰富API接口和插件机制,实现各种不同的信信功能。

11. Python Wechaty 采用了异步编程的方式,使用起来非常灵活方便,开发者可以根据自己的需求快速构建信信机器人。

12. 开发者可以通过阅读冠方文档和示例代码,快速上手和熟悉Python Wechaty 的使用方法,高效地实现信信机器人的功能。

Python Wechaty 的基本功能13. Python Wechaty 支持文本消息的发送和接收,开发者可以通过编写程序实现自动回复、消息转发等功能。

php开发api接口的实例代码

php开发api接口的实例代码

标题:PHP开发API接口的实例代码一、什么是API接口?API是应用程序接口(Application Programming Interface)的缩写,是软件系统间相互通信的一种方式。

API接口可以让不同的软件系统之间实现数据交换和功能调用,是现代软件开发中非常重要的一部分。

二、 PHP开发API接口的必要性1. 实现与其他系统的数据交换和功能调用2. 提高软件系统的可扩展性和灵活性3. 改善软件系统的易用性和用户体验三、 PHP开发API接口的基本步骤1. 设计接口的请求和响应数据结构在设计API接口时,需要确定接口的请求参数和响应数据的格式,包括数据类型、数据结构和数据校验规则等。

2. 编写接口的处理逻辑在PHP中,可以通过编写接口处理逻辑来实现API接口的功能。

接口的处理逻辑通常包括对请求参数的验证、业务逻辑的处理和返回响应数据等步骤。

3. 部署API接口部署API接口时,需要将编写好的接口处理逻辑部署到服务器上,并确保接口可以被外部系统访问。

四、 PHP开发API接口的实例代码下面通过一个简单的示例来演示如何使用PHP开发一个API接口。

1. 设计接口的请求和响应数据结构假设我们要开发一个获取用户信息的API接口,请求参数为用户ID,响应数据包括用户ID、用户名和电流信箱。

根据这个需求,我们可以设计如下的接口请求和响应数据结构:请求参数:- user_id:用户ID(整型,必填)响应数据:- user_id:用户ID(整型)- username:用户名(字符串)- email:电流信箱(字符串)2. 编写接口的处理逻辑接下来,我们可以编写PHP代码来处理这个API接口的功能。

以下是一个简单的示例代码:```php<?php// 接口请求处理逻辑if(isset($_GET['user_id'])){$user_id = $_GET['user_id'];// 根据用户ID查询用户信息,这里使用假数据作为示例$user_info = array('user_id' => $user_id, 'username' => '张三', 'email' => 'zhangsan@example');// 返回响应数据echo json_encode($user_info);} else {// 如果没有传入用户ID,则返回错误信息echo json_encode(array('error' => '缺少参数user_id'));}>```3. 部署API接口我们需要将编写好的接口处理逻辑部署到服务器上。

用Python进行微信公众号开发

用Python进行微信公众号开发

用Python进行微信公众号开发基础背景介绍正文开始说明:最好使用公网ip主机和备案的域名进行测试,本文测试使用的阿里云主机有公网ip,域名备案遇到坑了,买了域名无法在北京阿里云上备案,所以没有使用域名。

接入微信公众平台其实,微信api接口使用,这里主要是参考官网的说明部署的,步骤有点像曾经写过的一篇用zabbix实现微信报警的配置;想玩好了,除了要对使用的哪种语言本身熟悉,还要就是熟读微信的api接口文档了。

第一步:填写服务器配置nxinx扫描登陆免费的微信测试平台,填写接口配置信息:注意:微信公众号接口只支持80端口。

所以,在填写url时我是在阿里云上用nginx做的一个web服务。

阿里云主机上的nginx主要部分配置如下:第二步:验证消息的确来自微信服务器(即验证服务器地址的有效性):开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址url上,GET请求携带4个参数:1. signature:微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数;2.timestamp:时间戳;3.nonce:随机数;4.echostr:随即字符串;开发者通过检验signature对请求进行校验,若确认此处get请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败;阿里云主机上编写python代码,(以tonado框架为例)实现验证:运行代码:python wechat.py然后,回到微信开发平台,在填写完接口配置信息后,点击提交;一切正常,提交后会显示配置成功;下面,就可以根据个人用户关注开发的公众号所要实现哪些需求和微信的api文档开发相关功能了。

示例一:简单文本信息个人用户关注公众号后,用户输入字符串,公众号回显什么字符串;具体还要参考微信api文档:消息管理部分python代码:运行代码:python wechat.py。

微信公众平台接口php基础

微信公众平台接口php基础

字符串
$contentStr = "Welcome to wechat world!"; 连接. 13课天气预报$d1=$city.$da1.$w1.$p1.$q1; 调用location={$keyword} 字符串截取:26天气预报 strlen() utf-8,3位 substr($a,num,length) empty()
条件
if(条件){ } if () {} else {} if (){} elseif(){} else{}
替换
switch
case break case break default
遍历
foreach 30遍历数组
循环
while(条件) { }
XML
XML是一种简单的数据存储语言,它要求每一个标 签都有开始和结束标记,可以进行嵌套。如 <xml> <content> <title>我的书包</title> <book>语文书</book><book>数学书</book> </content> </xml>
微信公众平台接口 php基础
2020/6/16
微信公众平台接口傻瓜教程 /11356249 快速上手 灵活应用 官方文档wx_sample.php
编辑工具
记事本 editplus phpedit dreamwaver 行号
格式
<?php ?> ;{}()结束 注释: /** * wechat php test */
数学运算
$b=1; $b=$b+1; $b++; 16课第几个睡觉的 int flo

python实现微信自动回复(自动聊天)

python实现微信自动回复(自动聊天)

python实现微信⾃动回复(⾃动聊天)原⽂地址(本⼈):介绍微信⾃动回复其实主要就是登录,接收消息,回复消息三个功能,微信没有提供公开的API,但是可以分析⽹页版微信通信原理,通过模拟浏览器来实现需要的功能。

下⾯将给出微信⽹页版通信原理以及Python代码。

分析-获取uuid:GETParam _ (13位时间戳)Response window.QRLogin.code = 200; window.QRLogin.uuid = "4YyQFP2Daw==";-获取⼆维码:GET ==Param 4YyQFP2Daw== 即上⾯的uuidResponse ⼆维码图⽚-监听是否扫描⼆维码以及是否确认登录:GET https:///cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=4YyQFP2Daw==Param uuid 同上Responsewindow.code=200;window.redirect_uri="https:///cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ARxD7GSdBYtNHOxhK0BF0ek-@qrticket_0&uuid=4YyQFP2Daw==&lang=zh_CN&scan=1486743186";code:408 ⽆响应201 扫描⼆维码但没有登录(此时响应数据中还包含⽤户头像图⽚base64编码的字符串,UserAvatar)200 登录redirect_uri 为接下来需要请求的地址-获取后续访问所需要的key等GETParam URL为上次返回的redirect_uri 参数已经带上了Response<error><ret>0</ret><message/><skey>@crypt_828c27e0_e98d62f6954235194f2b1252943f25ad</skey><wxsid>0zEvAdWKm9ZZgYVn</wxsid><wxuin>1564527827</wxuin><pass_ticket>OLxGHwqL%2BWNArxvXaqjDy06qzdrSojq6DJwiBF19sgw2CibZSJBv1WwOXAfKnLIg</pass_ticket><isgrayscale>1</isgrayscale>< /error>-初始化POST https:///cgi-bin/mmwebwx-bin/webwxinit?r=-485039295&lang=zh_CN&pass_ticket=OLxGHwqL%2BWNArxvXaqjDy06qzdrSojq6DJwiBF19sgw2CibZSJBv1WwOXAfKnLIgParam r ( - + 9位随机数),pass_ticket,{"BaseRequest": {"Uin": "1564527827", "Skey": "@crypt_828c27e0_e98d62f6954235194f2b1252943f25ad", "DeviceID": "e924318232435460", "Sid": "0zEvAdWKm9ZZgYVn"}} 第三个参数其中为json数据,DeviceID为(e + 15位随机数)Response 返回json,包含⽤户⾃⼰的信息,最近联系⼈,订阅的公众号消息等等;这⾥只需要关注UserName=@821c154488cdddbfb04141aa8f681174305d21d67a24cfd6eca3e77a152e52ff 每位⽤户都有⼀个UserName,但是每次登陆UserName都是重新分配的,SyncKey 为⼀组key ,后⾯接收消息需要将其作为参数,同时每次接收接收消息时,也会返回⼀组SyncKey作为在下⼀次请求的参数,以此类推-状态检查这⾥会建⽴⼀个长连接,每次连接⼤约20秒左右,若新消息,⼿机端发出退出⽹页登录指令,或者状态异常会返回特定的状态码GET https:///cgi-bin/mmwebwx-bin/synccheck?r=1486743215000&skey=@crypt_828c27e0_e98d62f6954235194f2b1252943f25ad&sid=0zEvAdWKm9Z ZgYVn&uin=1564527827&deviceid=e891796429.95749&synckey=1_660530221%7C2_660530488%7C3_660530485%7C1000_1486721341&_=1486740215000 Paramr(时间戳),skey,sid,uin,deviceid,synckey(将SyncKey中的多组key 以 key1_value1|key2_value2 的形式拼接成字符串如:3_660530485|1000_1486721341),_ (时间戳) Responsewindow.synccheck={retcode:"0",selector:"2"}retcode=0 正常,1101 退出登录,1102 会话异常, selector= 0 ⽆变化 2or6 有消息-接收消息若状态检查到有新消息,则请求消息POST https:///cgi-bin/mmwebwx-bin/webwxsync?sid=0zEvAdWKm9ZZgYVn&skey=@crypt_828c27e0_e98d62f6954235194f2b1252943f25ad&lang=zh_CN&pass_ticket=OLxGHwqL%2BWNArxvXaqjDy06qzdrSojq6DJwiBF19sgw2CibZSJBv1 Paramsid,skey,pass_ticket 以及 json数据 {"SyncKey": {"Count": 4, "List": [{"Key": 1, "Val": 660530221}, {"Key": 2, "Val": 660530488}, {"Key": 3, "Val": 660530485}, {"Key":1000, "Val": 1486721341}]}, "BaseRequest": {"Sid": "0zEvAdWKm9ZZgYVn", "Skey": "@crypt_828c27e0_e98d62f6954235194f2b1252943f25ad", "DeviceID":"e141257009.76972", "Uin": "1564527827"}, "rr": "-888098293"} 其中rr (- + 9位随机数)Responsejson数据包含消息的所有信息,其中关注 FromUserName=@821c154488cdddbfb04141aa8f681174305d21d67a24cfd6eca3e77a152e52ff 消息发送者以及 Content消息内容-发送消息POST https:///cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket=0%2BoUqOWdYEen6oDVFEIv5ncIIaJcWs1LeSi69C8tUTgcp36azGAl6a8uT02PiaHuParam pass_ticket, json数据{"Msg": {"FromUserName": "@9e718026650771acd6d759922e000fafceaa1a5fda83aea7b3b70bc1bd6c3774", "LocalID":"14867488199507670", "ClientMsgId": "14867488199507670", "ToUserName": "@9e718026650771acd6d759922e000fafceaa1a5fda83aea7b3b70bc1bd6c3774","Content": "消息内容", "Type": "1"}, "BaseRequest": {"Sid": "5Qn7rswOtPRHFw92", "Skey": "@crypt_828c27e0_ad386b3d4d68a282eda03d7d5b2d3104","DeviceID": "e397471984070243", "Uin": "1564527827"}, "Scene": "0"} 其中LocalID,ClientMsgId 为13位时间戳加上5位随机数Response 返回响应的状态码,发送成功会返回 LocalID 和 ClientMsgID以上就是我们需要的知道的,当然其他⽐如读取所有联系⼈等都是⼤同⼩异,这⾥就不多赘述了。

微信API接口大全

微信API接口大全

微信API接⼝⼤全微信⼊⼝绑定,微信事件处理,微信API全部操作包含在这些⽂件中。

微信⽀付、微信红包、微信卡券、微信⼩店。

1. [代码]index.php<?phpinclude_once 'lib.inc.php';$wcObj = new WeChat("YOUKUIYUAN");$wcObj->wcValid();2. [代码]微信⼊⼝类<?php/*** Description of wechat** @author Administrator*/class WeChat extends WxApi{public $token = "";//put your code herepublic function __construct($token = "") {parent::__construct();$this->token = $token;}public function wcCheckSignature(){try{if (empty($this->token)) {throw new Exception('TOKEN is not defined!');}$signature = $_GET["signature"];$timestamp = $_GET["timestamp"];$nonce = $_GET["nonce"];$token = $this->token;$tmpArr = array($token, $timestamp, $nonce);// use SORT_STRING rulesort($tmpArr, SORT_STRING);$tmpStr = implode( $tmpArr );$tmpStr = sha1( $tmpStr );if( $tmpStr == $signature ){return true;}else{return false;}}catch (Exception $e) {echo 'Message: ' .$e->getMessage();}}public function wcValid(){$echoStr = isset($_GET["echostr"]) && !empty($_GET["echostr"]) ? addslashes($_GET["echostr"]) : NULL;if(is_null($echoStr)){$this->wcMsg();}else{//valid signature , optionif($this->wcCheckSignature()){echo $echoStr;exit;}else{exit();}}}public function wcMsg(){//get post data, May be due to the different environments$postStr = isset($GLOBALS["HTTP_RAW_POST_DATA"]) && !empty($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS["HTTP_RAW_POST_DATA"] : ""; if(!empty($postStr)){libxml_disable_entity_loader(true);$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);$this->zcLog(TRUE,$postObj);$fromUsername = $postObj->FromUserName;$toUsername = $postObj->ToUserName;$MsgType = $postObj->MsgType;if($MsgType == 'event'){//执⾏事件相应$Event = $postObj->Event;switch ($Event) {case 'subscribe'://关注break;case 'unsubscribe'://取消关注break;case 'SCAN'://扫描break;case 'LOCATION'://地址break;case 'CLICK'://点击时间break;case 'VIEW'://跳转break;case 'card_pass_check'://卡券审核通过break;case 'card_not_pass_check'://卡券审核失败break;case 'user_get_card'://⽤户领取卡券break;case 'user_del_card'://⽤户删除卡券break;case 'user_view_card'://⽤户浏览会员卡break;case 'user_consume_card'://⽤户核销卡券break;case 'merchant_order'://微⼩店⽤户下单付款break;default:break;}}else{switch ($MsgType) {case 'text'://⽂本格式break;case 'image'://图⽚格式break;case 'voice'://声⾳break;case 'video'://视频break;case 'shortvideo'://⼩视频break;case 'location'://上传地理位置break;case 'link'://链接相应break;default:break;}}////////////////////////////////////////////////////////////////////$keyword = trim($postObj->Content);$time = time();$textTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType><Content><![CDATA[%s]]></Content><FuncFlag>0</FuncFlag></xml>";if(!empty( $keyword )){$msgType = "text";$contentStr = "Welcome to wechat world!";$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr;}else{echo "Input something...";}////////////////////////////////////////////////////////////////////}else{echo "暂时没有任何信息!";exit;}}//⽇志LOGpublic function zcLog($errcode , $errmsg){$this->returnAy = array();$this->returnAy['errcode'] = $errcode;$this->returnAy['errmsg'] = $errmsg;$this->returnAy['errtime'] = date("Y-m-d H:i:s",time());$logfile = fopen("logfile_".date("Ymd",time()).".txt", "a+");$txt = json_encode($this->returnAy)."\n";fwrite($logfile, $txt);fclose($logfile);//return $this->returnAy;}}3. [代码]微信操作类 - 更新了⾃定义菜单部分<?php/********************************************************* @author Kyler You <QQ:2444756311>* @link /wiki/home/index.html* @version 2.0.1* @uses $wxApi = new WxApi();* @package 微信API接⼝陆续会继续进⾏更新********************************************************/class WxApi {//const appId = "";//const appSecret = "";const appId = "";const appSecret = "";//const mchid = ""; //商户号//const privatekey = ""; //私钥public $parameters = array();public function __construct(){}/***************************************************** 微信提交API⽅法,返回微信指定JSON****************************************************/public function wxHttpsRequest($url,$data = null){$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);if (!empty($data)){curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, $data);}curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($curl);curl_close($curl);return $output;}/***************************************************** 微信带证书提交数据 - 微信红包使⽤****************************************************/public function wxHttpsRequestPem($url, $vars, $second=30,$aHeader=array()){$ch = curl_init();//超时时间curl_setopt($ch,CURLOPT_TIMEOUT,$second);curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);//这⾥设置代理,如果有的话//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//以下两种⽅式需选择⼀种//第⼀种⽅法,cert 与 key 分别属于两个.pem⽂件//默认格式为PEM,可以注释curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/apiclient_cert.pem');//默认格式为PEM,可以注释curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/apiclient_key.pem');curl_setopt($ch,CURLOPT_CAINFO,'PEM');curl_setopt($ch,CURLOPT_CAINFO,getcwd().'/rootca.pem');//第⼆种⽅式,两个⽂件合成⼀个.pem⽂件//curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');if( count($aHeader) >= 1 ){curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);}curl_setopt($ch,CURLOPT_POST, 1);curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);$data = curl_exec($ch);if($data){curl_close($ch);return $data;}else {$error = curl_errno($ch);echo "call faild, errorCode:$error\n";curl_close($ch);return false;}}/***************************************************** 微信获取AccessToken 返回指定微信公众号的at信息****************************************************/public function wxAccessToken($appId = NULL , $appSecret = NULL){$appId = is_null($appId) ? self::appId : $appId;$appSecret = is_null($appSecret) ? self::appSecret : $appSecret;$data = json_decode(file_get_contents("access_token.json"));if ($data->expire_time < time()) {//echo $appId,$appSecret;$url = "https:///cgi-bin/token?grant_type=client_credential&appid=".$appId."&secret=".$appSecret;$result = $this->wxHttpsRequest($url);//print_r($result);$jsoninfo = json_decode($result, true);$access_token = $jsoninfo["access_token"];if ($access_token) {$data->expire_time = time() + 7000;$data->access_token = $access_token;$fp = fopen("access_token.json", "w");fwrite($fp, json_encode($data));fclose($fp);}}else {$access_token = $data->access_token;}return $access_token;}/***************************************************** 微信获取AccessToken 返回指定微信公众号的at信息****************************************************/public function wxJsApiTicket($appId = NULL , $appSecret = NULL){$appId = is_null($appId) ? self::appId : $appId;$appSecret = is_null($appSecret) ? self::appSecret : $appSecret;$data = json_decode(file_get_contents("jsapi_ticket.json"));if ($data->expire_time < time()) {$url = "https:///cgi-bin/ticket/getticket?type=jsapi&access_token=".$this->wxAccessToken();$result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);$ticket = $jsoninfo['ticket'];if ($ticket) {$data->expire_time = time() + 7000;$data->jsapi_ticket = $ticket;$fp = fopen("jsapi_ticket.json", "w");fwrite($fp, json_encode($data));fclose($fp);}}else {$ticket = $data->jsapi_ticket;}return $ticket;}/***************************************************** 微信通过OPENID获取⽤户信息,返回数组****************************************************/public function wxGetUser($openId){$wxAccessToken = $this->wxAccessToken();$url = "https:///cgi-bin/user/info?access_token=".$wxAccessToken."&openid=".$openId."&lang=zh_CN"; $result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);return $jsoninfo;}/***************************************************** 微信⽣成⼆维码ticket****************************************************/public function wxQrCodeTicket($jsonData){$wxAccessToken = $this->wxAccessToken();$url = "https:///cgi-bin/qrcode/create?access_token=".$wxAccessToken;$result = $this->wxHttpsRequest($url,$jsonData);return $result;}/***************************************************** 微信通过ticket⽣成⼆维码****************************************************/public function wxQrCode($ticket){$url = "https:///cgi-bin/showqrcode?ticket=" . urlencode($ticket);return $url;}/***************************************************** 发送⾃定义的模板消息****************************************************/public function wxSetSend($touser, $template_id, $url, $data, $topcolor = '#7B68EE'){$template = array('touser' => $touser,'template_id' => $template_id,'url' => $url,'topcolor' => $topcolor,'data' => $data);$jsonData = json_encode($template);$result = $this->wxSendTemplate($jsonData);return $result;}/***************************************************** 微信设置OAUTH跳转URL,返回字符串信息 - SCOPE = snsapi_base //验证时不返回确认页⾯,只能获取OPENID****************************************************/public function wxOauthBase($redirectUrl,$state = "",$appId = NULL){$appId = is_null($appId) ? self::appId : $appId;$url = "https:///connect/oauth2/authorize?appid=".$appId."&redirect_uri=".$redirectUrl."&response_type=code&scope=snsapi_base&state=".$state."#wechat_redirect"; return $url;}/***************************************************** 微信设置OAUTH跳转URL,返回字符串信息 - SCOPE = snsapi_userinfo //获取⽤户完整信息****************************************************/public function wxOauthUserinfo($redirectUrl,$state = "",$appId = NULL){$appId = is_null($appId) ? self::appId : $appId;$url = "https:///connect/oauth2/authorize?appid=".$appId."&redirect_uri=".$redirectUrl."&response_type=code&scope=snsapi_userinfo&state=".$state."#wechat_redirect"; return $url;}/***************************************************** 微信OAUTH跳转指定URL****************************************************/public function wxHeader($url){header("location:".$url);}/***************************************************** 微信通过OAUTH返回页⾯中获取AT信息****************************************************/public function wxOauthAccessToken($code,$appId = NULL , $appSecret = NULL){$appId = is_null($appId) ? self::appId : $appId;$appSecret = is_null($appSecret) ? self::appSecret : $appSecret;$url = "https:///sns/oauth2/access_token?appid=".$appId."&secret=".$appSecret."&code=".$code."&grant_type=authorization_code";$result = $this->wxHttpsRequest($url);//print_r($result);$jsoninfo = json_decode($result, true);//$access_token = $jsoninfo["access_token"];return $jsoninfo;}/***************************************************** 微信通过OAUTH的Access_Token的信息获取当前⽤户信息 // 只执⾏在snsapi_userinfo模式运⾏****************************************************/public function wxOauthUser($OauthAT,$openId){$url = "https:///sns/userinfo?access_token=".$OauthAT."&openid=".$openId."&lang=zh_CN";$result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);return $jsoninfo;}/***************************************************** 创建⾃定义菜单****************************************************/public function wxMenuCreate($jsonData){$wxAccessToken = $this->wxAccessToken();$url = "https:///cgi-bin/menu/create?access_token=" . $wxAccessToken;$result = $this->wxHttpsRequest($url,$jsonData);$jsoninfo = json_decode($result, true);return $jsoninfo;}/***************************************************** 获取⾃定义菜单****************************************************/public function wxMenuGet(){$wxAccessToken = $this->wxAccessToken();$url = "https:///cgi-bin/menu/get?access_token=" . $wxAccessToken;$result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);return $jsoninfo;}/***************************************************** 删除⾃定义菜单****************************************************/public function wxMenuDelete(){$wxAccessToken = $this->wxAccessToken();$url = "https:///cgi-bin/menu/delete?access_token=" . $wxAccessToken;$result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);return $jsoninfo;}/***************************************************** 获取第三⽅⾃定义菜单****************************************************/public function wxMenuGetInfo(){$wxAccessToken = $this->wxAccessToken();$url = "https:///cgi-bin/get_current_selfmenu_info?access_token=" . $wxAccessToken;$result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);return $jsoninfo;}/****************************************************** ⽣成随机字符串 - 最长为32位字符串*****************************************************/public function wxNonceStr($length = 16, $type = FALSE) {$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";$str = "";for ($i = 0; $i < $length; $i++) {$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);}if($type == TRUE){return strtoupper(md5(time() . $str));}else {return $str;}}/******************************************************** 微信商户订单号 - 最长28位字符串*******************************************************/public function wxMchBillno($mchid = NULL) {if(is_null($mchid)){if(self::mchid == "" || is_null(self::mchid)){$mchid = time();}else{$mchid = self::mchid;}}else{$mchid = substr(addslashes($mchid),0,10);}return date("Ymd",time()).time().$mchid;}/******************************************************** 微信格式化数组变成参数格式 - ⽀持url加密*******************************************************/public function wxSetParam($parameters){if(is_array($parameters) && !empty($parameters)){$this->parameters = $parameters;return $this->parameters;}else{return array();}}/******************************************************** 微信格式化数组变成参数格式 - ⽀持url加密*******************************************************/public function wxFormatArray($parameters = NULL, $urlencode = FALSE){if(is_null($parameters)){$parameters = $this->parameters;}$restr = "";//初始化空ksort($parameters);//排序参数foreach ($parameters as $k => $v){//循环定制参数if (null != $v && "null" != $v && "sign" != $k) {if($urlencode){//如果参数需要增加URL加密就增加,不需要则不需要$v = urlencode($v);}$restr .= $k . "=" . $v . "&";//返回完整字符串}}if (strlen($restr) > 0) {//如果存在数据则将最后“&”删除$restr = substr($restr, 0, strlen($restr)-1);}return $restr;//返回字符串}/******************************************************** 微信MD5签名⽣成器 - 需要将参数数组转化成为字符串[wxFormatArray⽅法]*******************************************************/public function wxMd5Sign($content, $privatekey){try {if (is_null($privatekey)) {throw new Exception("财付通签名key不能为空!");}if (is_null($content)) {throw new Exception("财付通签名内容不能为空");}$signStr = $content . "&key=" . $privatekey;return strtoupper(md5($signStr));}catch (Exception $e){die($e->getMessage());}}/******************************************************** 微信Sha1签名⽣成器 - 需要将参数数组转化成为字符串[wxFormatArray⽅法]*******************************************************/public function wxSha1Sign($content){try {if (is_null($content)) {throw new Exception("签名内容不能为空");}//$signStr = $content;return sha1($content);}catch (Exception $e){die($e->getMessage());}}/******************************************************** 微信jsApi整合⽅法 - 通过调⽤此⽅法获得jsapi数据*******************************************************/public function wxJsapiPackage(){$jsapi_ticket = $this->wxJsApiTicket();// 注意 URL ⼀定要动态获取,不能 hardcode.$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = $protocol.$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];$timestamp = time();$nonceStr = $this->wxNonceStr();$signPackage = array("jsapi_ticket" => $jsapi_ticket,"nonceStr" => $nonceStr,"timestamp" => $timestamp,"url" => $url);// 这⾥参数的顺序要按照 key 值 ASCII 码升序排序$rawString = "jsapi_ticket=$jsapi_ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";//$rawString = $this->wxFormatArray($signPackage);$signature = $this->wxSha1Sign($rawString);$signPackage['signature'] = $signature;$signPackage['rawString'] = $rawString;$signPackage['appId'] = self::appId;return $signPackage;}/******************************************************** 将数组解析XML - 微信红包接⼝*******************************************************/public function wxArrayToXml($parameters = NULL){if(is_null($parameters)){$parameters = $this->parameters;}if(!is_array($parameters) || empty($parameters)){die("参数不为数组⽆法解析");}$xml = "<xml>";foreach ($arr as $key=>$val){if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">";}else$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";}$xml.="</xml>";return $xml;}/******************************************************** 微信卡券:上传LOGO - 需要改写动态功能*******************************************************/public function wxCardUpdateImg() {$wxAccessToken = $this->wxAccessToken();//$data['access_token'] = $wxAccessToken;$data['buffer'] = '@D:\\workspace\\htdocs\\yky_test\\logo.jpg';$url = "https:///cgi-bin/media/uploadimg?access_token=".$wxAccessToken;$result = $this->wxHttpsRequest($url,$data);$jsoninfo = json_decode($result, true);return $jsoninfo;//array(1) { ["url"]=> string(121) "/mmbiz/ibuYxPHqeXePNTW4ATKyias1Cf3zTKiars9PFPzF1k5icvXD7xW0kXUAxHDzkEPd9micCMCN0dcTJfW6Tnm93MiaAfRQ/0" }}/******************************************************** 微信卡券:获取颜⾊*******************************************************/public function wxCardColor(){$wxAccessToken = $this->wxAccessToken();$url = "https:///card/getcolors?access_token=".$wxAccessToken;$result = $this->wxHttpsRequest($url);$jsoninfo = json_decode($result, true);return $jsoninfo;}/******************************************************** 微信卡券:创建卡券*******************************************************/public function wxCardCreated($jsonData) {$wxAccessToken = $this->wxAccessToken();$url = "https:///card/create?access_token=" . $wxAccessToken;$result = $this->wxHttpsRequest($url,$jsonData);$jsoninfo = json_decode($result, true);return $jsoninfo;}/******************************************************** 微信卡券:JSAPI 卡券Package - 基础参数没有附带任何值 - 再⽣产环境中需要根据实际情况进⾏修改*******************************************************/public function wxCardPackage($cardId){$timestamp = time();$api_ticket = $this->wxJsApiTicket();$cardId = $cardId;$arrays = array($api_ticket,$timestamp,$cardId);sort($arrays);$string = sha1(implode("",$arrays));$resultArray['card_id'] = $cardId;$resultArray['card_ext'] = array();$resultArray['card_ext']['openid'] = 'oOmn4s9MiwqHSNNvPn0dBtU23toA';$resultArray['card_ext']['timestamp'] = $timestamp;$resultArray['card_ext']['signature'] = $string;return $resultArray;}}4. [代码]微信JSAPI<?phprequire_once 'lib.inc.php';$wx = new WxApi();//通过⽹页获取openid//if(!isset($_GET['code'])){// header("location:https:///connect/oauth2/authorize?appid=".WxApi::appId."&redirect_uri=http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']."&response_type=code&scope=snsapi_base&state=1#wechat_redirect"); //}//else{// $CODE = $_GET['code'];// $Info = $wx->wxOauthAccessToken($CODE);//print_r($Info);// $openId = $Info['openid'];//}////////////////////////////////////////////$signPackage = $wx->wxJsapiPackage();//print_r($signPackage);$kqInfo = $wx->wxCardPackage("");$listInfo = $wx->wxCardListPackage();><html><head><title>JSAPI接⼝测试</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script src="/jquery-1.11.2.min.js"></script><script src="/open/js/jweixin-1.0.0.js"></script></head><body><div><input type="button" id="batchAddCard" name="batchAddCard" value="添加卡券" /><br /><input type="button" id="openCard" name="openCard" value="拉起卡券库" /><br /><input type="button" id="ShareTimeLine" name="ShareTimeLine" value="分享朋友圈" /><br /><div id="showInfo"></div></div><script>wx.config({debug: false,appId: '<?php echo $signPackage["appId"];?>',timestamp: <?php echo $signPackage["timestamp"];?>,nonceStr: '<?php echo $signPackage["nonceStr"];?>',signature: '<?php echo $signPackage["signature"];?>',jsApiList: [// 所有要调⽤的 API 都要加到这个列表中'onMenuShareTimeline','onMenuShareAppMessage','addCard','openCard']});wx.ready(function () {// 在这⾥调⽤ APIwx.onMenuShareAppMessage({title: '互联⽹之⼦',desc: '在长⼤的过程中,我才慢慢发现,我⾝边的所有事,别⼈跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有⾮得如此,事情是可以改变的。

php教程:APICloud微信、QQ登录分享实现方法及注意事项

php教程:APICloud微信、QQ登录分享实现方法及注意事项

php教程:APICloud微信、QQ登录分享实现方法及注意事项千锋PHP培训模拟面试阶段,是由讲师担任企业技术面试官,就业老师担任企业人事面试官,按照企业面试模式,先模拟面试再当场做面试点评,让学员提前感受面试氛围,更有针对性提升面试能力。

今天来为大家说一说APICloud 微信、QQ登录分享实现方法及注意事项。

针对用户最近的问题,对微信登录分享、QQ登录分享进行一个流程性的讲解。

在微信分享经常是分享不成功或者图片不显示,主要问题是图片过大或者是没有本地化。

在config.xml的配置就不多说了一、微信登录(使用wx模块)1、流程:使用auth进行授权--->getToken获取用户信息---->同步至服务端注意:在安卓端可以提示用户没有安装微信端,但是ios端切忌不要加任何提示2、代码实现:(因为会有一个唤起微信客户端的时间,代码里面加了showProgress过度了一下)1 2 3 4 5 var wx = api.require('wx');wx.auth({apiKey: ''//在此输入你的微信apikey }, function(ret, err){if(ret.status){6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 api.showProgress({style: 'default',animationType: 'fade',title: '登录中...',text: '请稍后...',modal: false});wx.getToken({//apiKey: '',//apiSecret: '',code: ret.code},function(ret, err){if(ret.status){//获取用户信息var accessToken = ret.accessToken;var openId = ret.openId;23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 wx.getUserInfo({accessToken: ret.accessToken,openId: ret.openId}, function(ret,err){if(ret.status){//将信息同步至服务器api.ajax({url: '',//你的服务器地址method: 'post',cache:true,timeout: 30,dataType: 'json',returnAll:false,data:{values:{nickname:ret.nickname,avatar:ret.headimgurl,40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 privilege:ret.privilege,unionid:ret.unionid,city:ret.city}}},function(ret,err){api.hideProgress();if(ret.code==1){api.toast({msg: '登录成功',duration:2000,location: 'top'});}else{api.alert({msg:''+ret.msg+''57 58 59 60 61 62 63 64 65 66 67 68 69 70 });}})}});}});}else{if(api.systemType=='android' && err.code==3){alert("请安装微信客户端");}}})二、微信分享以shareWebPage 为例进行代码说明,微信要求的是图片必须是本地图片,所有我们在分享之前必须将图片先保存至本地,可以使用api.download 的方法将图片保存到本地。

python模仿微信添加好友截图,一键批量生成微信添加好友聊天截图

python模仿微信添加好友截图,一键批量生成微信添加好友聊天截图

python模仿微信添加好友截图,⼀键批量⽣成微信添加好友聊天截图# -*- coding: utf-8 -*-import time,random,os,shutilimport PIL.Image as Imageimport PIL.ImageColor as ImageColorimport PIL.ImageDraw as ImageDrawimport PIL.ImageFont as ImageFont# from PIL import Image, ImageDraw"""整体思路:先⽣成时间等字符,然后再把头像,姓名获取到,缩⼩,圆⾓,合并,保存,移除已经添加过的头像名字代码还没优化暂时就这样把 后⾯有空在搞,author@:xiaoheQQ496631085python3.7"""quanju_path=[]def circle_corner(img, radii):"""圆⾓处理:param img: 源图象。

:param radii: 半径,如:30。

:return: 返回⼀个圆⾓处理后的图象。

"""# 画圆(⽤于分离4个⾓)circle = Image.new('L', (radii * 2, radii * 2), 0) # 创建⼀个⿊⾊背景的画布draw = ImageDraw.Draw(circle)draw.ellipse((0, 0, radii * 2, radii * 2), fill=255) # 画⽩⾊圆形# 原图img = img.convert("RGBA")w, h = img.size# 画4个⾓(将整圆分离为4个部分)alpha = Image.new('L', img.size, 255)alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0)) # 左上⾓alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0)) # 右上⾓alpha.paste(circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii)) # 右下⾓alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii)) # 左下⾓# alpha.show()img.putalpha(alpha) # ⽩⾊区域透明可见,⿊⾊区域不可见return imgdef ruiji_jpgname(path):all_img_name=os.listdir(path)# for x in range(1,len(all_img_name)):# 取随机数x=random.randint(1,len(all_img_name))name = fenge_houzui(all_img_name[x])# print(all_img_name[x])# 打印⽂件图⽚名称和后缀# 打印名称# print(fenge_houzui(all_img_name[x]))return name#对象,位置字体字体⼤⼩字体颜⾊添加内容def imgAddFont(im1,gps,font,fontSize,fontColor,data):# 在图⽚上添加⽂字 1draw = ImageDraw.Draw(im1)#设置字体time_font = ImageFont.truetype(font, fontSize)# (0,0):坐标 "内容":添加的字体 (0,0,255):字体颜⾊ font:字体⼤⼩draw.text(gps,data,fontColor,font=time_font)draw = ImageDraw.Draw(im1)def copy(h,m,z,n,v):#⼿机当前时间系统时间systime = str(h) + ":"+str(m)#⼩时随便减去多少add_h=random.randint(0,1)#分钟随便减去多少add_m=random.randint(2,7)#添加好友的时间addtime = str(h-add_h) + ":"+str(m-add_m)#标题名称# qun_name = "电销 " + nqun_name = ruiji_jpgname(".\\img")# 打开头像原图检测是否存在不存在就换个后缀jpg_path = '.\\img\\' + (str(qun_name))if os.path.exists(jpg_path+".jpg"):img = Image.open(jpg_path+".jpg")else:print(jpg_path)img = Image.open(jpg_path+".png")# 关闭打开⽂件,移动⽂件# Image.close()quanju_path.append(jpg_path+".jpg")#电池电量diannum = str(v)#打开图⽚im1=Image.open("new.png")#系统时间 (宽⾼)imgAddFont(im1,(17,20),'C:\Windows\Fonts\msyh.ttc',38,(50,50,50),systime)#电池电量imgAddFont(im1,(1012,21),'C:\Windows\Fonts\simhei.ttf',29,(50,50,50),diannum)#群姓名imgAddFont(im1,(120,108),'C:\Windows\Fonts\msyh.ttc',49,(50,50,50),qun_name)#添加时间imgAddFont(im1,(490,260),'C:\Windows\Fonts\msyh.ttc',38,(170,170,170),addtime)# #发消息时间# imgAddFont(im1,(490,260),'C:\Windows\Fonts\msyh.ttc',38,(170,170,170),addtime)# 保存位置 22 370# img=im1# 已经添加好完整的⽂字了,下⾯添加图⽚打开缩略圆⾓合并#缩放等⽐例的尺⼨w, h = img.sizeimg.thumbnail((118, 118)) # 尺⼨等⽐缩放img_touxiang = circle_corner(img, radii=10)# 打开底图layer = Image.new('RGBA', im1.size, (0,0,0,0))layer.paste(img_touxiang, (20, 370))out=posite(layer,im1,layer)# out.save("target.png")save_time=time.strftime('%Y_%m_%d_%M_%H',time.localtime(time.time()))out.save(".\\end\\"+save_time +str(z)+".png")# out.save("target.png")def fenge_houzui(file_name,fu='.'):# 分割后缀,返回⽂件名字z = file_name.split(fu)print(file_name)print(z)if len(z)>2:z = file_name.split('.jp')return z[0]# 程序⼊⼝h=int(input("请输⼊⼿机⼏点"))m=int(input("请输⼊现在⼏分"))v=int(input("请输⼊现在电量"))z=int(input("请输⼊需要⽣成多少张图⽚"))# 判断⽣成多少个图⽚for x in range(1,z+1):if z<2:n=input("请输⼊标题昵称例如好友")copy(h,m,x,n,v)copy(h,m,x,"__",v)# 把已经⽣成过的就移动到end⽂件夹⾥⾯for x in range(0,len(quanju_path)):try:print(quanju_path[x])shutil.move(quanju_path[x],".\\img_end")except Exception as e:raise e整体思路:先⽣成时间等字符,然后再把头像,姓名获取到,缩⼩,圆⾓,合并,保存,移除已经添加过的头像名字代码还没优化暂时就这样把 后⾯有空在搞,author@:xiaoheQQ496631085python3.7只需要创建2个⽂件夹 img(⾥⾯是放的头像,头像命名就是⽹名)和end(存放最后的截图)img_end(程序把⽤过的头像放到⾥⾯的)。

Python轻量级web框架bottle使用方法解析

Python轻量级web框架bottle使用方法解析

Python轻量级web框架bottle使⽤⽅法解析Bottle是⼀个轻量级的Web框架,此框架只由⼀个 bottle.py ⽂件构成,不依赖任何第三⽅模块。

#!/usr/bin/env python# -*- coding:utf-8 -*-from bottle import template, Bottleapp = Bottle()@app.route('/say')def index():return "Hello World"# return template('<b>Hello {{name}}</b>!', name="bottle")if __name__ == '__main__':app.run(server="tornado",host='0.0.0.0', port=8888)1、路由系统路由系统是的url对应指定函数,当⽤户请求某个url时,就由指定函数处理当前请求,对于Bottle的路由系统可以分为⼀下⼏类:静态路由动态路由请求⽅法路由⼆级路由1.1静态路由@app.route("/login") # 默认为get请求def hello():return """<form action="/login" method="post">Username:<input name="username" type="text" />Password:<input name="password" type="password" /><input value="Login" type="submit"/></form>"""@app.route("/login",method="POST")def do_login():username = request.forms.get("username")password = request.forms.get("password")print(username,password)if username and password:return "<p>login success</p>"else:return "<p>login failure</p>"1.2动态路由@app.route('/say/<name>')def callback(name):return template('<b>Hello {{name}}</b>!')@app.route('/say/<id:int>')def callback(id):return template('<b>Hello {{id}}</b>!')@app.route('/say/<name:re:[a-z]+>')def callback(name):return template('<b>Hello {{name}}</b>!')@app.route('/static/<path:path>')def callback(path):return static_file(path, root='static')1.3请求⽅法路由@app.route('/hello/', method='POST') # 等同于@app.post('/hello/')def index():...@app.get('/hello/') # 等同于@app.route('/hello/',method='GET')def index():...@app.post('/hello/') # 等同于@app.route('/hello/',method='POST')def index():...@app.put('/hello/') # 等同于@app.route('/hello/',method='PUT')def index():...@app.delete('/hello/')def index():...1.4⼆级路由#!/usr/bin/env python# -*- coding:utf-8 -*-from bottle import template, Bottleapp01 = Bottle()@app01.route('/hello/', method='GET')def index():return template('<b>App01</b>!')app01.py#!/usr/bin/env python# -*- coding:utf-8 -*-from bottle import template, Bottleapp02 = Bottle()@app02.route('/hello/', method='GET')def index():return template('<b>App02</b>!')app02.py#!/usr/bin/env python# -*- coding:utf-8 -*-from bottle import template, Bottlefrom bottle import static_fileapp = Bottle()@app.route('/hello/')def index():return template('<b>Root {{name}}</b>!', name="bottle")from root_dir import app01from root_dir import app02app.mount('app01', app01.app01)app.mount('app02', app02.app02)app.run(host='localhost', port=8888)1.5静态⽂件映射,static_file()函数⽤于响应静态⽂件的请求# 静态⽂件映射,static_file()函数⽤于响应静态⽂件的请求@app.route("/static/<filename:re:.*\.jpg>")def send_image(filename):return static_file(filename, root=os.getcwd(), mimetype="image/jpg") @app.route("/static/<filename:path>") # 可匹配路径def send_image(filename):return static_file(filename, root=os.getcwd(), mimetype="image/jpg") # 强制下载@app.route("/static/<filename:path>") # 可匹配路径def download(filename):return static_file(filename, root=os.getcwd(), download=filename)1.6使⽤error()函数⾃定义错误页⾯@app.error(404)def error404(error):return "我找不到⽬标了,我发⽣错误了"1.7HTTP错误和重定向abort()函数是⽣成HTTP错误的页⾯的⼀个捷径@app.route("/restricted")def restricted()abort(401,"Sorry, access denied")# 将url重定向到其他url,可以在location中设置新的url,接着返回⼀个303 # redirect()函数可以帮助我们做这件事@app.route("/wrong/url")def wrong()redirect("/right/url")其他异常除了HTTPResponse或者HTTPError以外的其他异常,都会导致500错误,因此不会造成WSGI服务器崩溃将bottle.app().catchall的值设为False来关闭这种⾏为,以便在中间件中处理异常2.cookies@app.route("/login", method="POST")def do_login():username = request.forms.get("username")password = request.forms.get("password")print(username, password)if username and password:response.set_cookie("name",username, secret= 'some-secret-key') # 设置cookiereturn "<p>login success</p>"else:return "<p>login failure</p>"@app.route("/static/<filename:re:.*\.jpg>")def send_image(filename):username = request.get_cookie("name", secret= 'some-secret-key') # 获取cookieif username:return static_file(filename, root=os.getcwd(), mimetype="image/jpg")else:return "verify failed"bottle就的 set_cookie 的默认 path 是当前路径,也就是说,在这个页⾯上存⼊的 cookie 在别的页⾯通常是取不到的,不熟悉这点的⼈⼏乎都要栽在这⾥。

用Python玩转微信(一)

用Python玩转微信(一)

⽤Python玩转微信(⼀)欢迎⼤家访问我的个⼈⽹站《刘江的博客和教程》:主要分享Python 及Django教程以及相关的博客然⽽,貌似⽤的Python2版本,并且每次执⾏都要重复扫码登录,这对于我这种Python3的⽤户是不⾏的。

动起⼿来,⾃⼰⼲!1. 安装相应的库pip install itchatpip install echarts-python2. 实现登陆状态保存:import itchatitchat.auto_login(hotReload=True)itchat.dump_login_status()这样你就可以保持⼀段时间登录状态,⽽不⽤每次运⾏代码都要扫码登录了!⾸次登录,程序会弹出⼀个⼆维码图⽚窗⼝,⽤微信⼿机客户端扫码就可以登录了!3. 使⽤饼图展⽰个⼈好友性别分布有⼀个echarts-python库可以帮助你⽅便的使⽤python代码在浏览器中展⽰百度Echart图。

但是,但是,这个库是Python2的,Python3⽤起来⽔⼟不服,没办法只好根据错误修改库的源码!下图显⽰了应该改的两个地⽅(其实还有很多地⽅)。

改完库的源码,就可以执⾏代码了。

借⽤前⼈的代码,修改了⼀下:#!/usr/bin/env python# -*- coding:utf-8 -*-import itchatitchat.auto_login(hotReload=True)itchat.dump_login_status()friends = itchat.get_friends(update=True)[:]total = len(friends) - 1male = female = other = 0for friend in friends[1:]:sex = friend["Sex"]if sex == 1:male += 1elif sex == 2:female += 1else:other += 1# print("男性好友:%.2f%%" % (float(male) / total * 100))# print("⼥性好友:%.2f%%" % (float(female) / total * 100))# print("其他:%.2f%%" % (float(other) / total * 100))from echarts import Echart, Legend, Piechart = Echart('%s的微信好友性别⽐例' % (friends[0]['NickName']), 'from WeChat')e(Pie('WeChat',[{'value': male, 'name': '男性 %.2f%%' % (float(male) / total * 100)},{'value': female, 'name': '⼥性 %.2f%%' % (float(female) / total * 100)},{'value': other, 'name': '其他 %.2f%%' % (float(other) / total * 100)}],radius=["50%", "70%"]))e(Legend(["male", "female", "other"]))del chart.json["xAxis"]del chart.json["yAxis"]chart.plot()运⾏代码,测试⼀下,成功在浏览器展⽰出来了:我好想暴露了什么....4. 好友个性签名词云分析好友信息,能发现个性签名,可以⽤它做词云。

python实现网站微信登录的示例代码

python实现网站微信登录的示例代码

python实现⽹站微信登录的⽰例代码最近微信登录开放公测,为了⽅便微信⽤户使⽤,我们的产品也决定加上微信登录功能,然后就有了这篇笔记。

根据需求选择相应的登录⽅式python实现⽹站微信登录的⽰例代码微信现在提供两种登录接⼊⽅式移动应⽤微信登录⽹站应⽤微信登录这⾥我们使⽤的是⽹站应⽤微信登录按照1 注册并通过开放平台开发者资质认证注册微信开放平台帐号后,在帐号中⼼中填写开发者资质认证申请,并等待认证通过。

2 创建⽹站应⽤通过填写⽹站应⽤名称、简介和图标,以及各平台下载地址等资料,创建⽹站应⽤3 接⼊微信登录在资源中⼼查阅⽹站应⽤开发⽂档,开发接⼊微信登陆功能,让⽤户可使⽤微信登录你的⽹站应⽤如果已经完成上⾯的操作,请继续往下看微信⽹站应⽤微信登录是基于构建的微信OAuth2.0授权登录系统。

微信OAuth2.0授权登录⽬前⽀持authorization_code模式,适⽤于拥有server端的应⽤授权。

该模式整体流程为:1. 第三⽅发起微信授权登录请求,微信⽤户允许授权第三⽅应⽤后,微信会拉起应⽤或重定向到第三⽅⽹站,并且带上授权临时票据code参数;2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;3. 通过access_token进⾏接⼝调⽤,获取⽤户基本数据资源或帮助⽤户实现基本操作。

具体流程请参考官⽅⽂档,我们这⾥只说⼀下python的实现⽅法。

官⽅⽂档地址不过现在还只有微信接⼊、获取⽤户信息、刷新refresh_token 等简单功能⾸先需要把代码clone到本地然后执⾏python setup.py install使⽤⽅式⾮常简单from weixin.client import WeixinAPIAPP_ID = 'your app id'APP_SECRET = 'your app secret'REDIRECT_URI = 'http://your_/redirect_uri' # 这⾥⼀定要注意地址⼀定要加上http/httpsscope = ("snsapi_login", )api = WeixinAPI(appid=APP_ID,app_secret=APP_SECRET,redirect_uri=REDIRECT_URI)authorize_url = api.get_authorize_url(scope=scope)现在将现在我们就可以使⽤code 来获取登录的 access_tokenaccess_token = api.exchange_code_for_access_token(code=code)access_token 信息为{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE"}参数说明access_token接⼝调⽤凭证(有效期⽬前为2个⼩时)expires_in access_token接⼝调⽤凭证超时时间,单位(秒)refresh_token⽤户刷新access_token(有效期⽬前为30天)openid授权⽤户唯⼀标识scope⽤户授权的作⽤域,使⽤逗号(,)分隔获取access_token后,就可以进⾏接⼝调⽤,有以下前提:1. access_token有效且未超时;2. 微信⽤户已授权给第三⽅应⽤帐号相应接⼝作⽤域(scope)。

pythonitchat实现调用微信接口的第三方模块方法

pythonitchat实现调用微信接口的第三方模块方法

pythonitchat实现调⽤微信接⼝的第三⽅模块⽅法itchat是⼀个开源的微信个⼈号接⼝,使⽤python调⽤微信从未如此简单。

使⽤不到三⼗⾏的代码,你就可以完成⼀个能够处理所有信息的微信机器⼈。

当然,该api的使⽤远不⽌⼀个机器⼈,更多的功能等着你来发现,⽐如这些。

该接⼝与公众号接⼝共享类似的操作⽅式,学习⼀次掌握两个⼯具。

如今微信已经成为了个⼈社交的很⼤⼀部分,希望这个项⽬能够帮助你扩展你的个⼈的微信号、⽅便⾃⼰的⽣活。

【⽂章背景】最近⼏天⼲啥都不来劲,昨晚偶然了解到Python⾥的itchat包,它已经完成了wechat的个⼈账号API接⼝,使爬取个⼈微信信息更加⽅便。

鉴于⾃⼰很早之前就想知道诸如⾃⼰微信好友性别⽐例都来⾃哪个城市之类的问题,于是乎玩⼼⼀起,打算爬⼀下⾃⼰的微信。

⾸先,在终端安装⼀下itchat包。

pip install itchat安装完成后导⼊包,再登陆⾃⼰的微信。

过程中会⽣产⼀个登陆⼆维码,扫码之后即可登陆。

登陆成功后,把⾃⼰好友的相关信息爬下来。

import itchatitchat.login()#爬取⾃⼰好友相关信息,返回⼀个json⽂件friends = itchat.get_friends(update=True)[0:]有了上⾯的friends数据,我们就可以来做好友或者朋友圈数据分析啦!python实现微信接⼝(itchat)安装sudo pip install itchat登录itchat.auto_login() 这种⽅法将会通过微信扫描⼆维码登录,但是这种登录的⽅式确实短时间的登录,并不会保留登录的状态,也就是下次登录时还是需要扫描⼆维码,如果加上hotReload==True,那么就会保留登录的状态,⾄少在后⾯的⼏次登录过程中不会再次扫描⼆维码,该参数⽣成⼀个静态⽂件itchat.pkl⽤于存储登录状态退出及登录完成后调⽤的特定的⽅法这⾥主要使⽤的是灰调函数的⽅法,登录完成后的⽅法需要赋值在 loginCallback 中退出后的⽅法,需要赋值在 exitCallback中.若不设置 loginCallback 的值, 将会⾃动删除⼆维码图⽚并清空命令⾏显⽰.import itchat, timedef lc():print("Finash Login!")def ec():print("exit")itchat.auto_login(loginCallback=lc, exitCallback=ec)time.sleep()itchat.logout() #强制退出登录回复消息sendsend(msg="Text Message", toUserName=None)参数:msg : ⽂本消息内容@fil@path_to_file : 发送⽂件@img@path_to_img : 发送图⽚@vid@path_to_video : 发送视频toUserName : 发送对象, 如果留空, 将发送给⾃⼰.返回值True or False实例代码# coding-utf-8import itchatitchat.auto_login()itchat.send("Hello World!")ithcat.send("@fil@%s" % '/tmp/test.text')ithcat.send("@img@%s" % '/tmp/test.png')ithcat.send("@vid@%s" % '/tmp/test.mkv')send_msgsend_msg(msg='Text Message', toUserName=None),其中的的msg是要发送的⽂本,toUserName是发送对象, 如果留空, 将发送给⾃⼰,返回值为True或者False实例代码import itchatitchat.auto_login()itchat.send_msg("hello world.")send_filesend_file(fileDir, toUserName=None) fileDir是⽂件路径, 当⽂件不存在时, 将打印⽆此⽂件的提醒,返回值为True或者False实例代码import itchatitchat.auto_login()itchat.send_file("/tmp/test.txt")send_imagesend_image(fileDir, toUserName=None) 参数同上实例代码import itchatitchat.auto_login()itchat.send_img("/tmp/test.txt")send_video(fileDir, toUserName=None) 参数同上实例代码import itchatitchat.auto_login()itchat.send_video("/tmp/test.txt")注册消息⽅法itchat 将根据接受到的消息类型寻找对应的已注册的⽅法.如果⼀个消息类型没有对应的注册⽅法, 该消息将会被舍弃.在运⾏过程中也可以动态注册⽅法, 注册⽅式与结果不变.注册⽅法不带具体对象注册, 将注册为普通消息的回复⽅法.import itchatfrom itchat.content import *@itchat.msg_register(TEXT) #这⾥的TEXT表⽰如果有⼈发送⽂本消息,那么就会调⽤下⾯的⽅法def simple_reply(msg):#这个是向发送者发送消息itchat.send_msg('已经收到了⽂本消息,消息内容为%s'%msg['Text'],toUserName=msg['FromUserName'])return "T reveived: %s" % msg["Text"] #返回的给对⽅的消息,msg["Text"]表⽰消息的内容带对象参数注册, 对应消息对象将调⽤该⽅法,其中isFriendChat表⽰好友之间,isGroupChat表⽰群聊,isMapChat表⽰公众号import itchatfrom itchat.content import *@itchat.msg_register(TEXT, isFriendChat=True, isGroupChat=True,isMpChat=True)def text_reply(msg):er.send("%s : %s" % (mst.type, msg.text))消息类型向注册⽅法传⼊的 msg 包含微信返回的字典的所有内容.itchat 增加 Text, Type(也就是参数) 键值, ⽅便操作.itcaht.content 中包含所有的消息类型参数, 如下表参数l类型Text 键值TEXT⽂本⽂本内容(⽂字消息)MAP地图位置⽂本(位置分享)CARD名⽚推荐⼈字典(推荐⼈的名⽚)SHARING分享分享名称(分享的⾳乐或者⽂章等)PICTURE 下载⽅法图⽚/表情RECORDING语⾳下载⽅法ATTACHMENT附件下载⽅法VIDEO⼩视频下载⽅法FRIENDS好友邀请添加好友所需参数SYSTEM系统消息更新内容的⽤户或群聊的UserName组成的列表NOTE通知通知⽂本(消息撤回等)附件的下载与发送itchat 的附件下载⽅法存储在 msg 的 Text 键中.发送的⽂件名(图⽚给出的默认⽂件名), 都存储在 msg 的 FileName 键中.下载⽅法, 接受⼀个可⽤的位置参数(包括⽂件名), 并将⽂件响应的存储.注意:下载的⽂件存储在指定的⽂件中,直接将路径与FileName连接即可,如msg["Text"]('/tmp/weichat'+msg['FileName'])@itchat.msg_register([PICTURE, RECORDING, ATTACHMENT, VIDEO])def download_files(msg):#msg.download(msg['FileName']) #这个同样是下载⽂件的⽅式msg['Text'](msg['FileName']) #下载⽂件#将下载的⽂件发送给发送者itchat.send('@%s@%s' % ('img' if msg['Type'] == 'Picture' else 'fil', msg["FileName"]), msg["FromUserName"])群消息增加了三个键值,如下:isAt 判断是否 @ 本号ActualNickName : 实际 NickName(昵称)Content : 实际 Content测试程序import itcahtfrom itchat.content import TEXT@itchat.msg_register(TEXT, isGroupChat=True)def text_reply(msg):if(msg.isAt): #判断是否有⼈@⾃⼰#如果有⼈@⾃⼰,就发⼀个消息告诉对⽅我已经收到了信息itchat.send_msg("我已经收到了来⾃{0}的消息,实际内容为{1}".format(msg['ActualNickName'],msg['Text']),toUserName=msg['FromUserName'])itchat.auto_login()itchat.run()注册消息的优先级消息内容注意:所有的消息内容都是可以⽤键值对来访问的,如msg["FromUserName]就是查看发送者,itchat.search_friends(userName=msg['FromUserName'])['NickName']查看的是当发送者昵称⼀般消息⼀般的消息都遵循以下的内容:{"FromUserName": "","ToUserName": "","Content": "","PlayLength": 0,"RecommendInfo": {},"StatusNotifyCode": 0,"NewMsgId": "","Status": 0,"VoiceLength": 0,"ForwardFlag": 0,"AppMsgType": 0,"Ticket": "","AppInfo": {},"Url": "","ImgStatus": 0,"MsgType": 0,"ImgHeight": 0,"MediaId": "","MsgId": "","FileName": "","HasProductId": 0,"FileSize": "","CreateTime": 0,"SubMsgType": 0}初始化消息MsgType: 51FromUserName: ⾃⼰IDToUserName: ⾃⼰IDStatusNotifyUserName: 最近联系的联系⼈IDContent:<msg><op id='4'><username># 最近联系的联系⼈filehelper,xxx@chatroom,wxid_xxx,xxx,...</username><unreadchatlist><chat><username># 朋友圈MomentsUnreadMsgStatus</username><lastreadtime>1454502365</lastreadtime></chat></unreadchatlist><unreadfunctionlist># 未读的功能账号消息,群发助⼿,漂流瓶等</unreadfunctionlist></op></msg>⽂本消息MsgType: 1FromUserName: 发送⽅IDToUserName: 接收⽅IDContent: 消息内容图⽚消息itchat 增加了 Text 键, 键值为下载该图⽚的⽅法.MsgType: 3FromUserName: 发送⽅IDToUserName: 接收⽅IDMsgId: ⽤于获取图⽚,⽤于表⽰每⼀条消息Content:<msg><img length="6503" hdlength="0" /><commenturl></commenturl></msg>拓展:如果想要得到Content中的具体内容可以使⽤正则表达式匹配出来视频消息*itchat 增加了 Text 键, 键值为下载该视频的⽅法.*MsgType: 62FromUserName: 发送⽅IDToUserName: 接收⽅IDMsgId: ⽤于获取⼩视频Content:<msg><img length="6503" hdlength="0" /><commenturl></commenturl></msg>地理位置消息itchat 增加了 Text 键, 键值为该地点的⽂本形式.MsgType: 1FromUserName: 发送⽅IDToUserName: 接收⽅IDContent: /cgi-bin/redirectforward?args=xxxOriContent:<?xml version="1.0"?><msg><location x="34.195278" y="117.177803" scale="16" label="江苏省徐州市铜⼭区新区海河路" maptype="0" poiname="江苏师范⼤学⼤学⽣公寓园区" /></msg>名⽚消息itchat 增加了Text 键, 键值为该调⽤ add_friend 需要的属性.MsgType: 42FromUserName: 发送⽅IDToUserName: 接收⽅IDContent:<?xml version="1.0"?><msg bigheadimgurl="" smallheadimgurl="" username="" nickname="" shortpy="" alias="" imagestatus="3" scene="17" province="" city="" sign="" sex="1" certflag="0" certinfo="" brandIconUrl="" brandHomeUrl="" brandSubscriptConfigUrl="" brandFlags="0{"UserName": "xxx", # ID,这⾥的是昵称"Province": "xxx","City": "xxx","Scene": 17,"QQNum": 0,"Content": "","Alias": "xxx", # 微信号"OpCode": 0,"Signature": "","Ticket": "","Sex": 0, # 1:男, 2:⼥"NickName": "xxx", # 昵称"AttrStatus": 4293221,"VerifyFlag": 0}下⾯是添加好友的测试代码@itchat.msg_register(itchat.content.CARD,isFriendChat=True)def simply(msg):print msg['Text']print msg['Content']itchat.add_friend(userName=msg['Text']['UserName']) #添加推荐的好友print msg['RecommendInfo']print msg['RecommendInfo']['UserName']语⾳消息*itchat增加了Text键,键值为下载该语⾳⽂件的⽅法,下载下来的是MP3的格式MsgType: 34FromUserName: 发送⽅IDToUserName: 接收⽅IDMsgId: ⽤于获取语⾳Content:<msg><voicemsg endflag="1" cancelflag="0" forwardflag="0" voiceformat="4" voicelength="1580" length="2026" bufid="216825389722501519" clientmsgid="49efec63a9774a65a932a4e5fcd4e923filehelper174_1454602489" fromusername="" /></msg>下载⽅法:msg['Text'](msg['FileName'])动画表情itchat添加了Text键,键值为下载该图⽚表情的⽅法。

Python微信--分享接口(分享到朋友圈、朋友、空间)

Python微信--分享接口(分享到朋友圈、朋友、空间)

Python微信--分享接⼝(分享到朋友圈、朋友、空间)⽣成JS-SDK权限验证的签名获取signature(签名)⾸先要获得1、#获得jsapi_ticket2、#获取当前页⾯的url #获取当前页⾯的url url="{}://{}{}".format(self.request.protocol,self.request.host,self.request.uri)3、#获取timestamp(时间戳) #获取timestamp(时间戳) timestamp = int(time.time())4、#获取noncestr(随机字符串) #获取noncestr(随机字符串) nonceStr = self.createNonceStr()(见下函数)5、# 这⾥参数的顺序要按照 key 值 ASCII 码升序排序string = "jsapi_ticket={}&noncestr={}&timestamp={}&url={}".format(jsapiTicket,nonceStr,timestamp,url)6、#得到signature(⽤sha1加密)signature = hashlib.sha1(string).hexdigest();1、获得jsapi_ticket要先获取access_token(不再细说)然后def getJsApiTicket(self):#获得jsapi_ticket #获得jsapi_ticket之后,就可以⽣成JS-SDK权限验证的签名了 import urllib2 # jsapi_ticket 应该全局存储与更新,以下代码以写⼊到⽂件中做⽰例 #cookie('ticket',null); #获取access_token accessToken = self.accesstokens() # 如果是企业号⽤以下 URL 获取 ticket # $url = "https:///cgi-bin/get_jsapi_ticket?access_token=$accessToken"; #获取jsapi_ticket url = "https:///cgi-bin/ticket/getticket?access_token={}&type=jsapi".format(accessToken) req = urllib2.Request(url) res_data = urllib2.urlopen(req) res = res_data.read() res=json_decode(res) return str(res['ticket'])4、#获取noncestr(随机字符串)def createNonceStr(self,length = 16):#获取noncestr(随机字符串)import randomchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"str = "";for i in range(0,16):str += chars[random.randint(0, len(chars)-1):random.randint(0, len(chars)-1)+1]# for ($i = 0; $i < $length; $i++) {# $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);# }return str;后台总代码整理为:def index(self):"""知识中⼼:return:"""id = self.get_argument('id','')getSignPackage=self.getSignPackage()self.assign('getSignPackage',getSignPackage)self.display('knowledge/index.html')def getSignPackage(self) :import hashlib#获得jsapi_ticketjsapiTicket = self.getJsApiTicket()# 注意 URL ⼀定要动态获取,不能 hardcode.# protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";# $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";#获取当前页⾯的urlurl="{}://{}{}".format(self.request.protocol,self.request.host,self.request.uri)#获取timestamp(时间戳)timestamp = int(time.time())#获取noncestr(随机字符串)nonceStr = self.createNonceStr()# 这⾥参数的顺序要按照 key 值 ASCII 码升序排序string = "jsapi_ticket={}&noncestr={}&timestamp={}&url={}".format(jsapiTicket,nonceStr,timestamp,url)#得到signaturesignature = hashlib.sha1(string).hexdigest();signPackage = {"appId":wxinfo['appid'],"nonceStr":nonceStr,"timestamp":timestamp,"url":url,"signature":signature,"rawString":string}return signPackage;def createNonceStr(self,length = 16):#获取noncestr(随机字符串)import randomchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"str = "";for i in range(0,16):str += chars[random.randint(0, len(chars)-1):random.randint(0, len(chars)-1)+1]# for ($i = 0; $i < $length; $i++) {# $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);# }return str;def getJsApiTicket(self):#获得jsapi_ticket#获得jsapi_ticket之后,就可以⽣成JS-SDK权限验证的签名了import urllib2# jsapi_ticket 应该全局存储与更新,以下代码以写⼊到⽂件中做⽰例#cookie('ticket',null);#获取access_tokenaccessToken = self.accesstokens()# 如果是企业号⽤以下 URL 获取 ticket# $url = "https:///cgi-bin/get_jsapi_ticket?access_token=$accessToken";#获取jsapi_ticketurl = "https:///cgi-bin/ticket/getticket?access_token={}&type=jsapi".format(accessToken)req = urllib2.Request(url)res_data = urllib2.urlopen(req)res = res_data.read()res=json_decode(res)return str(res['ticket'])前台总代码整理:<script type="text/javascript" src="/static/js/jquery.js"></script><script type="text/javascript" src="/open/js/jweixin-1.0.0.js"></script><script type="text/javascript">//通过config接⼝注⼊权限验证配置wx.config({debug: false,appId: '${getSignPackage["appId"]}',timestamp:'${getSignPackage["timestamp"]}',nonceStr: '${getSignPackage["nonceStr"]}',signature: '${getSignPackage["signature"]}',jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline','onMenuShareQQ','onMenuShareWeibo'// 所有要调⽤的 API 都要加到这个列表中]});wx.ready(function () {// 1 判断当前版本是否⽀持指定 JS 接⼝,⽀持批量判断wx.checkJsApi({jsApiList: ['onMenuShareAppMessage'],success: function (res) {//alert(JSON.stringify(res));}});//获取“分享给朋友”按钮点击状态及⾃定义分享内容接⼝wx.onMenuShareAppMessage({title: '${replypt_list["title"]}',desc: '${replypt_list["title"]}',link: '${getSignPackage["url"]}',imgUrl: '${handler.settings["PHOTO_URL"]}${replypt_list["cover"]}',trigger: function (res) {// 不要尝试在trigger中使⽤ajax异步请求修改本次分享的内容,因为客户端分享操作是⼀个同步操作,这时候使⽤ajax的回包会还没有返回 },success: function (res) {$.ajax({url: '/shop/knowledge/addIntager',data: { name: "${replypt_list['id']}"},type: 'post',cache:false,success: function(data){},error: function(xhr, type){alert('Ajax error!')}})},cancel: function (res) {},fail: function (res) {}});//获取“分享到朋友圈”按钮点击状态及⾃定义分享内容接⼝wx.onMenuShareTimeline({title: '${replypt_list["title"]}',desc: '${replypt_list["title"]}',link: '${getSignPackage["url"]}',imgUrl: '${handler.settings["PHOTO_URL"]}${replypt_list["cover"]}',trigger: function (res) {// 不要尝试在trigger中使⽤ajax异步请求修改本次分享的内容,因为客户端分享操作是⼀个同步操作,这时候使⽤ajax的回包会还没有返回 },success: function (res) {$.ajax({url: '/shop/knowledge/addIntager',data: { name: "${replypt_list['id']}"},type: 'post',cache:false,success: function(data){alert(str('aa'))error: function(xhr, type){alert('Ajax error!')}})},cancel: function (res) {},fail: function (res) {}});//获取“分享到QQ”按钮点击状态及⾃定义分享内容接⼝wx.onMenuShareQQ({title: '${replypt_list["title"]}',desc: '${replypt_list["title"]}',link: '${getSignPackage["url"]}',imgUrl: '${handler.settings["PHOTO_URL"]}${replypt_list["cover"]}',trigger: function (res) {},complete: function (res) {},success: function (res) {$.ajax({url: '/shop/knowledge/addIntager',data: { name: "${replypt_list['id']}"},type: 'post',cache:false,success: function(data){},error: function(xhr, type){alert('Ajax error!')}})},cancel: function (res) {},fail: function (res) {}});wx.onMenuShareWeibo({title: '${replypt_list["title"]}',desc: '${replypt_list["title"]}',link: '${getSignPackage["url"]}',imgUrl: '${handler.settings["PHOTO_URL"]}${replypt_list["cover"]}',trigger: function (res) {},complete: function (res) {},success: function (res) {$.ajax({url: '/shop/knowledge/addIntager',data: { name: "${replypt_list['id']}"},type: 'post',cache:false,success: function(data){},error: function(xhr, type){ alert('Ajax error!') } }) }, cancel: function (res) { }, fail: function (res) { }。

Python爬虫实战练习:爬取微信公众号文章

Python爬虫实战练习:爬取微信公众号文章

Python爬虫实战练习:爬取微信公众号文章前言本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者:徐洲更为了实现该爬虫我们需要用到如下工具•Chrome浏览器•Python 3 语法知识•Python的Requests库此外,这个爬取程序利用的是微信公众号后台编辑素材界面。

原理是,当我们在插入超链接时,微信会调用专门的API(见下图),以获取指定公众号的文章列表。

因此,我们还需要有一个公众号。

PS:如有需要Python学习资料的小伙伴可以加下方的群去找免费管理员领取点击加群即可免费获取Python学习资料可以免费领取源码、项目实战视频、PDF文件等正式开始我们需要登录微信公众号,点击素材管理,点击新建图文消息,然后点击上方的超链接。

接着,按F12,打开Chrome的开发者工具,选择Network此时在之前的超链接界面中,点击「选择其他公众号」,输入你需要爬取的公众号(例如中国移动)此时之前的Network就会刷新出一些链接,其中以"appmsg"开头的便是我们需要分析的内容我们解析请求的URLhttps:///cgi-bin/appmsg?action=list_ex&begin=0&count=5&fakeid=MzI1MjU5MjMzNA==&type=9&query=&token=143406284&lang=zh _CN&f=json&ajax=1它分为三个部分•https:///cgi-bin/appmsg: 请求的基础部分•action=list_ex: 常用于动态网站,实现不同的参数值而生成不同的页面或者返回不同的结果•&begin=0&count=5&fakeid: 用于设置?里的参数,即begin=0, count=5通过不断的浏览下一页,我们发现每次只有begin会发生变动,每次增加5,也就是count的值。

python实现微信小程序反编译效果

python实现微信小程序反编译效果

python实现微信⼩程序反编译效果对某⼤神⽂件进⾏⼆次开发实现python实现微信⼩程序反编译对于⼩程序反编译想必⼤家都不陌⽣并且也有许多⼤神给出了⾃⼰的⽅法具体可以参考下可能是我本⼈技术的问题,很多⽅法我都没有成功并且⼤部分都是在命令⾏进⾏,很不⽅便所以就重新修改了⼀下,并进⾏封装效果图k ey = PBKDF2(wxid.encode("utf-8"),salt.encode("utf-8"),32,count=1000,hmac_hash_module=SHA1,)# ⽣成key# 读取加密的内容with open(file, mode="rb") as f:dataByte = f.read()# 初始化密钥cipher = AES.new(key, AES.MODE_CBC, iv.encode("utf-8"))# 解密头部1024个字节originData = cipher.decrypt(dataByte[WXAPKG_FLAG_LEN : 1024 + WXAPKG_FLAG_LEN])# 初始化xor密钥, 解密剩余字节xorKey = 0x66if len(wxid) >= 2:xorKey = ord(wxid[len(wxid) - 2])afData = dataByte[1024 + WXAPKG_FLAG_LEN :]out = bytearray()for i in range(len(afData)):out.append(afData[i] ^ xorKey)originData = originData[0:1023] + out# 保存解密后的数据with open(put, mode="wb") as f:f.write(originData)到此这篇关于python实现微信⼩程序反编译的⽂章就介绍到这了,更多相关python微信⼩程序反编译内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

我的第一个pythonweb开发框架(14)——后台管理系统登录功能

我的第一个pythonweb开发框架(14)——后台管理系统登录功能

我的第⼀个pythonweb开发框架(14)——后台管理系统登录功能 接下来正式进⼊⽹站的功能开发。

要完成后台管理系统登录功能,通过查看登录页⾯,我们可以了解到,我们需要编写验证码图⽚获取接⼝和登录处理接⼝,然后在登录页⾯的HTML上编写AJAX。

在进⾏接⼝开发之前,还有⼀个重要的事情要处理,那就是对站点进⾏初始化,如果不进⾏初始化,那么独⽴⽂件编写的接⼝将会找不到,要将异常错误写⼊⽇志⽂件也会找不到路径,下⾯先上代码。

打开main.py⽂件,改为下⾯代码(⼤家可以⽐较⼀下和之前代码有什么不同)1#!/usr/bin/evn python2# coding=utf-834import bottle5import sys6import os7import logging8import urllib.parse9from bottle import default_app, get, run, request, hook10from beaker.middleware import SessionMiddleware1112# 导⼊⼯具函数包13from common import web_helper, log_helper14# 导⼊api代码模块(初始化api⽂件夹⾥的各个访问路由,这⼀句不能删除,删除后将⽆法访问api⽂件夹⾥的各个接⼝)15import api1617#############################################18# 初始化bottle框架相关参数19#############################################20# 获取当前main.py⽂件所在服务器的绝对路径21 program_path = os.path.split(os.path.realpath(__file__))[0]22# 将路径添加到python环境变量中23 sys.path.append(program_path)24# 让提交数据最⼤改为2M(如果想上传更多的⽂件,可以在这⾥进⾏修改)25 bottle.BaseRequest.MEMFILE_MAX = 1024 * 1024 * 22627#############################################28# 初始化⽇志相关参数29#############################################30# 如果⽇志⽬录log⽂件夹不存在,则创建⽇志⽬录31if not os.path.exists('log'):32 os.mkdir('log')33# 初始化⽇志⽬录路径34 log_path = os.path.join(program_path, 'log')35# 定义⽇志输出格式与路径36 logging.basicConfig(level=,37 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',38 filename="%s/info.log" % log_path,39 filemode='a')4041# 设置session参数42 session_opts = {43'session.type': 'file',44'session.cookie_expires': 3600,45'session.data_dir': '/tmp/sessions/simple',46'session.auto': True47 }484950 @hook('before_request')51def validate():52"""使⽤勾⼦处理接⼝访问事件"""5354# 获取当前访问的Url路径55 path_info = request.environ.get("PATH_INFO")56# 过滤不⽤做任何操作的路由(即过滤不⽤进⾏判断是否登录和记录⽇志的url)57if path_info in ['/favicon.ico', '/', '/api/verify/']:58return59### 记录客户端提交的参数 ###60# 获取当前访问url路径与ip61 request_log = 'url:' + path_info + ' ip:' + web_helper.get_ip()62try:63# 添加json⽅式提交的参数64if request.json:65 request_log = request_log + ' params(json):' + urllib.parse.unquote(str(request.json))66except:67pass68try:69# 添加GET⽅式提交的参数70if request.query_string:71 request_log = request_log + ' params(get):' + urllib.parse.unquote(str(request.query_string))72# 添加POST⽅式提交的参数73if request.method == 'POST':74 request_log = request_log + ' params(post):' + urllib.parse.unquote(str(request.params.__dict__))75# 存储到⽇志⽂件中76 log_(request_log)77except:78pass7980# 处理ajax提交的put、delete等请求转换为对应的请求路由(由于AJAX不⽀持RESTful风格提交,所以需要在这⾥处理⼀下,对提交⽅式进⾏转换)81if request.method == 'POST'and request.POST.get('_method'):82 request.environ['REQUEST_METHOD'] = request.POST.get('_method', '')8384# 过滤不⽤进⾏登录权限判断的路由(登录与退出登录不⽤检查是否已经登录)85 url_list = ["/api/login/", "/api/logout/"]86if path_info in url_list:87pass88else:89# 已经登录成功的⽤户session肯定有值,没有值的就是未登录90 session = web_helper.get_session()91# 获取⽤户id92 manager_id = session.get('id', 0)93 login_name = session.get('login_name', 0)94# 判断⽤户是否登录95if not manager_id or not login_name:96 web_helper.return_raise(web_helper.return_msg(-404, "您的登录已失效,请重新登录"))979899100# 函数主⼊⼝101if__name__ == '__main__':102 app_argv = SessionMiddleware(default_app(), session_opts)103 run(app=app_argv, host='0.0.0.0', port=9090, debug=True, reloader=True)104else:105# 使⽤uwsgi⽅式处理python访问时,必须要添加这⼀句代码,不然⽆法访问106 application = SessionMiddleware(default_app(), session_opts)View Code main.py⽂件⾥有详细的注释说明,所以不进⾏细说,在这⾥讲⼀讲⽂件⼤体的思路。

python api接口开发案例

python api接口开发案例

在Python中,我们可以使用各种库来创建API接口。

常用的库包括Flask、Django、FastAPI等。

以下是一个使用Flask库创建API 接口的基本示例:```pythonfrom flask import Flask, jsonifyapp = Flask(__name__)# 假设我们有一个用户数据库,这里我们只是简单地列出一些用户users = [{"id":1,"name":"Alice","email":"*****************"},{"id":2,"name":"Bob","email":"***************"}, ]# 定义一个基础路由,返回所有用户@app.route('/users', methods=['GET'])def get_all_users():return jsonify(users)# 定义一个带参数的路由,返回特定用户@app.route('/users/<int:user_id>', methods=['GET'])def get_user(user_id):for user in users:if user['id'] == user_id:return jsonify(user)return jsonify({'error': 'User not found.'}), 404if __name__ == '__main__':app.run(debug=True)```在这个例子中,我们定义了两个API接口:1. GET /users: 返回所有用户的列表。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

这篇文章主要介绍了在Python的Bottle框架中使用微信API的示例,作者还在文中给出了一个生成的微信可扫描的二维码图,需要的朋友可以参考下
微信这个东西估计宅男没几个不熟悉的吧,微信经过这么两年多的发展终于向开放平台跨出了友好的一步。

蛋疼的以为微信会出一个详细的api等接口,兴奋不已的去申请了微信公共平台,然后开始找各种api的位置……
花费了近一个小时,依然没找到……
最后动用Google大杀器,终于找到了这么个链接。

我了个去的,没比这还简单的api 文档了吧。

最让人无法理解的是:居然没有本地开发环境支持,每次都要放在生产环境去调试。

最让人欣慰的是:就那么俩方法,生产环境调试几次也就完事了。

Python(bottle)版代码如下:
# -*- coding:utf-8 -*-
from bottle import debug, default_app, run, get, request, post
import sys, os, time, libxml2dom
@get('/')
def index():
return request.GET.get('echostr')
@post('/')
def index_post():
for key, value in request.POST.allitems():
doc = libxml2dom.parseString(key)
_to = doc.xpath('//FromUserName')[0].textContent
_from = doc.xpath('//ToUserName')[0].textContent
#_content = doc.xpath('//Content')[0].textContent
return """&lt;xml&gt;
&lt;ToUserName&gt;&lt;![CDATA[%s]]&gt;&lt;/ToUserName&gt;
&lt;FromUserName&gt;&lt;![CDA TA[%s]]&gt;&lt;/FromUserName&gt;
&lt;CreateTime&gt;%s&lt;/CreateTime&gt;
&lt;MsgType&gt;&lt;![CDATA[text]]&gt;&lt;/MsgType&gt;
&lt;Content&gt;&lt;![CDA TA[%s]]&gt;&lt;/Content&gt;
&lt;FuncFlag&gt;0&lt;/FuncFlag&gt;
&lt;/xml&gt;"""%(_to, _from, int(time.time()), u'我了个去啊')
if __name__ == "__main__":
# Interactive mode
debug(True)
port = int(sys.argv[1] if len(sys.argv) &gt; 1 else 8888)
run(host='0.0.0.0', port=port, reloader=True)
else:
# Mod WSGI launch
os.chdir(os.path.dirname(__file__))
app = default_app()
更多信息请查看IT技术专栏。

相关文档
最新文档