目录
- 一、微信了解
- 二、微信公众号开发—准备工作
- 1、appID、appsecret
- 2、Ngrok获得公网域名
- 3、测试验证是否配置成功
- 三、微信公众号开发—实现自动回复文本/图片
- 四、微信公众号开发—获取accessToken
- 五、微信公众号开发—网页授权拉取用户信息
- 1、操作步骤
- 2、python脚本实现
- 3、html模板
一、微信了解
1、微信相关功能
- 公众平台服务号、订阅号、企业微信、小程序的相关说明
- 接口权限功能
2、公众号
类型 |
功能 |
适用人群 |
订阅号 |
为媒体和个人提供一种新的信息传播方式,主要功能是在微信侧给用户传达资讯;(功能类似报纸杂志,提供新闻信息或娱乐趣事) |
个人、媒体、企业、政府或其他组织 |
服务号 |
为企业和组织提供更强大的业务服务与用户管理能力,主要偏向服务类交互(功能类似12315,114,银行,提供绑定信息,服务交互的) |
媒体、企业、政府或其他组织 |
区别 |
订阅号 |
服务号 |
发送次数 |
每天多一次 |
每月最多一次 |
显示位置 |
消息折叠出现在订阅号的文件夹中,不会收到微信提醒 |
消息出现在微信聊天列表中,会像收到消息一样有微信提醒 |
支付功能 |
无 |
认证的服务号有支付功能 |
二、微信公众号开发—准备工作
1、appID、appsecret
- 微信公众号开发需要appID、appsecret,可使用微信开发平台测试账号扫码登录获取;
2、Ngrok获得公网域名
- 微信公众号开发需要公网ip域名,可以使用Ngrok它可以把你的本地ip映射成一个公网域名,比如127.0.0.1:8080>http://wecht.test.idce.com
- 比如URL填写http://wecht.test.idce.com/wechat ; Token填写Testha
![Python开发微信公众号_第1张图片](http://img.e-com-net.com/image/info8/807ea407e8854b54b4918d81df312773.jpg)
3、测试验证是否配置成功
- 运行Ngrok(python sunny.py --clientid=*****)>运行python脚本>提交配置>显示配置成功
![Python开发微信公众号_第2张图片](http://img.e-com-net.com/image/info8/ad2e85d0d3004920a7ec387752ef79bd.jpg)
- python脚本如下,常量部分需替换成自己的, 第一次接入微信服务器的验证流程图;
![Python开发微信公众号_第3张图片](http://img.e-com-net.com/image/info8/5ec6590350ce4558b312c33e75339a16.jpg)
from flask import Flask, request, abort, render_template
import hashlib
WECHAT_TOKEN = "***"
WECHAT_APPID = "****"
WECHAT_APPSECRET = "*****"
app = Flask(__name__)
@app.route("/wechat", methods=["GET", "POST"])
def wechat():
"""对接微信公众号服务器"""
signature = request.args.get("signature")
timestamp = request.args.get("timestamp")
nonce = request.args.get("nonce")
if not all([signature, timestamp, nonce]):
abort(400)
li = [WECHAT_TOKEN, timestamp, nonce]
li.sort()
tmp_str = "".join(li)
sign = hashlib.sha1(tmp_str.encode("utf-8")).hexdigest()
if signature != sign:
abort(403)
else:
if request.method == "GET":
echostr = request.args.get("echostr")
if not echostr:
abort(400)
return echostr
if __name__ == '__main__':
app.run(host="127.0.0.1", port=8080, debug=True)
三、微信公众号开发—实现自动回复文本/图片
- 接收普通消息,当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上
1、代码流程图
![Python开发微信公众号_第4张图片](http://img.e-com-net.com/image/info8/b30ea5dbe614424bb9bd36db72fe5786.jpg)
2、python脚本实现
- 运行Ngrox,以及python脚本,在浏览器打开http://wecht.test.idce.com/wechat(wecht.test.idce.com替换成你自己的域名)
- 手机扫描测试号二维码,在手机端的公众号发送消息,即可体验自动回复内容
![Python开发微信公众号_第5张图片](http://img.e-com-net.com/image/info8/ce1a08ac641f4aff84949008486afbcf.jpg)
from flask import Flask, request, abort, render_template
import hashlib
import xmltodict
import time
WECHAT_TOKEN = "*****"
WECHAT_APPID = "*****"
WECHAT_APPSECRET = "*****"
app = Flask(__name__)
@app.route("/wechat", methods=["GET", "POST"])
def wechat():
"""对接微信公众号服务器"""
signature = request.args.get("signature")
timestamp = request.args.get("timestamp")
nonce = request.args.get("nonce")
if not all([signature, timestamp, nonce]):
abort(400)
li = [WECHAT_TOKEN, timestamp, nonce]
li.sort()
tmp_str = "".join(li)
sign = hashlib.sha1(tmp_str.encode("utf-8")).hexdigest()
if signature != sign:
abort(403)
else:
if request.method == "GET":
echostr = request.args.get("echostr")
if not echostr:
abort(400)
return echostr
elif request.method == "POST":
xml_data = request.data
if not xml_data:
abort(400)
xml_dict = xmltodict.parse(xml_data)
xml_dict = xml_dict.get("xml")
msg_type = xml_dict.get("MsgType")
content = xml_dict.get("Content")
if content == "hello":
content = "hello,小可爱"
resp_dict = {
"xml": {
"ToUserName": xml_dict.get("FromUserName"),
"FromUserName": xml_dict.get("ToUserName"),
"CreateTime": int(time.time()),
}
}
if msg_type == "text":
resp_dict['xml'].update({
"MsgType": "text",
"Content": content
})
elif msg_type == "image":
resp_dict['xml'].update({
"MsgType": "image",
"Image": {
"MediaId": xml_dict.get("MediaId")
},
})
else:
resp_dict['xml'].update({
"MsgType": "text",
"Content": "非文本,非图片内容"
})
resp_xml_str = xmltodict.unparse(resp_dict)
return resp_xml_str
if __name__ == '__main__':
app.run(host="127.0.0.1", port=8080, debug=True)
四、微信公众号开发—获取accessToken
- access_token是公众号的全局唯一接口调用凭据,有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效
1、python脚本实现
- 运行Ngrox,以及python脚本;浏览器打开http://wecht.test.idce.com/accestoken(wecht.test.idce.com替换成你自己的域名),即可获得accesstoken
![在这里插入图片描述](http://img.e-com-net.com/image/info8/45d766ec602641738e5f85e5c24d44c1.jpg)
from flask import Flask
import requests
WECHAT_TOKEN = "****"
WECHAT_APPID = "****"
WECHAT_APPSECRET = "****"
app = Flask(__name__)
@app.route("/accestoken")
def acc():
url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=" \
f"client_credential&appid={WECHAT_APPID}&secret={WECHAT_APPSECRET}"
resp = requests.get(url)
text = resp.text
return text
if __name__ == '__main__':
app.run(host="127.0.0.1", port=8080, debug=True)
五、微信公众号开发—网页授权拉取用户信息
1、操作步骤
- 运行python脚本,并运行Ngrox(python sunny.py --clientid=你的clientid);
- 接口权限区域:修改OAuth2.0授权回调页面域名(你的公网域名,例如wecht.test.idce.com);
![Python开发微信公众号_第6张图片](http://img.e-com-net.com/image/info8/d6cf7ffb76a54c0b930558637b7f65fe.jpg)
- 编写授权url如下,APPID替换成你自己的,REDIRECT_URI替换成http%3A//wecht.test.idce.com/wechat/index(wecht.test.idce.com替换成你自己的域名)
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE
- 在微信里打开上面的编好的授权url,即可显示用户信息
![Python开发微信公众号_第7张图片](http://img.e-com-net.com/image/info8/df5d91fd7a5e48ea91cd4a9cd807f894.jpg)
2、python脚本实现
- 运行Ngrox,以及python脚本;浏览器打开http://wecht.test.idce.com/wechat/index(wecht.test.idce.com替换成你自己的域名),会显示无code;
from flask import Flask, request, render_template
import requests
WECHAT_TOKEN = "****"
WECHAT_APPID = "****"
WECHAT_APPSECRET = "****"
app = Flask(__name__)
@app.route("/wechat/index")
def index():
code = request.args.get("code")
if not code:
return "无code"
url = f"https://api.weixin.qq.com/sns/oauth2/access_token?" \
f"appid={WECHAT_APPID}&secret={WECHAT_APPSECRET}&" \
f"code={code}&grant_type=authorization_code"
response = requests.get(url)
resp_dict = response.json()
if "errcode" in resp_dict:
return "获取access_token失败"
access_token = resp_dict.get("access_token")
open_id = resp_dict.get("openid")
url = f"https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={open_id}&lang=zh_CN"
response = requests.get(url)
user_resp_dict = response.json()
if "errcode" in user_resp_dict:
return "获取用户信息失败"
else:
return render_template("index.html", user=user_resp_dict)
if __name__ == '__main__':
app.run(host="127.0.0.1", port=8080, debug=True)
3、html模板
- 在templates文件夹下新建index.html
![在这里插入图片描述](http://img.e-com-net.com/image/info8/54521528c13d4dcca2fe593c5a96e8e6.jpg)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{user["nickname"]}}title>
head>
<body>
<img alt="头像" src="{{user['headimgurl']}}">
<table>
<tr>
<th>openidth>
<td>{{user['openid']}}td>
tr>
<tr>
<th>provinceth>
<td>{{user['province']}}td>
tr>
<tr>
<th>cityth>
<td>{{user['city']}}td>
tr>
table>
body>
html>