由于工作关系需要开发微信公众号,在这里记录一下本人在部署服务器过程当中碰到的壁。本文记录了在windows平台使用IIS部署基于python环境的Flask网站的主要步骤以及遇到的问题,希望有所帮助。
微信公众号开发我觉得还是比较繁琐,不过微信有相应的开发文档,内容会比较多,可以仔细研究一下。微信公众号申请好之后左边有一个 “> 开发” 模块,需要配置服务器,因为微信需要一个能够接收消息的本地服务器。在这里卡了挺长时间,试过好多个方法,也尝试过使用ngrok反向代理服务等,都不是长久之计。幸好本地有服务器,网络映射最终选择使用IIS部署python。使用IIS是为了解决80端口被占用的问题(443需要认证,更麻烦)。
Flask是一个用python编写的轻量级Web应用,基于WSGI工具箱。下面是一个最简单的flask网站应用,因为80端口可能被占用,所以开8080测试:
# base.py
from flask import Flask
app = Flask(__name__)
app.debug = True
@app.route("/")
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(port=8080)
运行base.py后访问8080会显示如上,表示成功。
打开控制面板--所有控制面板项--程序和功能--启用或关闭windows功能找到并安装IIS和CGI,打开会比较慢。(借用一张图)
wfastcgi使用WSGI和FastCGI在IIS和python之间提供了一个桥梁,他可以与任何支持WSGI的Python web应用程序或框架一起使用,并提供了一种通过IIS处理请求和处理池的有效方法。
打开命令行,通过pip安装,我已经安装过所以显示安装好了:
之后进入python安装目录下的scripts文件夹运行wfastcgi-enable,我用的是anaconda,注意用管理员权限运行:
"e:\anaconda\python.exe|e:\anaconda\lib\site-packages\wfastcgi.py"这个路径非常重要,保存一下,后续会在程序映射时候用到。
在Flask程序的同级目录下新建web.config文件,下面是web.config的示例:
其中scriptProcessor就是上面的路径,WSGI_HANDLER的value是f需要运行的lask程序,注意xml的格式错误。
打开IIS管理面板,新建一个网站,按需求填好名称、路径、端口等,路径即是flask程序所在路径,因为微信公众号要求是80端口,所以端口也填80。
打开网站下的处理程序映射模块,右边添加模块映射。路径填*,模块选FastCgiModule,可执行文件填上面保存的那个路径,名称随意。点击请求限制,将仅当请求映射至一下内容是才调用处理程序的√去掉。
提交之后会报错:不能在此路径中使用此配置节balabala,查了很久才发现是IIS访问和执行权限不够,执行以下命令,打开命令行进入到Flask程序所在路径:
执行下面两条命令(不懂是什么意思):
icacls . /grant "NT AUTHORITY\IUSR:(OI)(CI)(RX)"
icacls . /grant "Builtin\IIS_IUSRS:(OI)(CI)(RX)"
之后80端口就映射成功,外网可以访问你的Flask程序了。
至于微信公众号的配置原理在开发文档里面已经很详细了,不再解释,URL填写你的Flask程序开发的接口,Token就是密码,最好选明文模式。先不提交,等部署好服务器之后再点提交,否则会一直报错。
编写后台程序:
import hashlib
from flask import Flask, request, make_response
app = Flask(__name__)
app.debug = True
@app.route("/")
def hello():
return "Hello World!"
@app.route('/wechat_api/', methods=['GET', 'POST'])
def wechat():
if request.method == 'GET':
token = '这里填写公众号配置的token'
data = request.args
signature = data.get('signature', '')
timestamp = data.get('timestamp', '')
nonce = data.get('nonce', '')
echostr = data.get('echostr', '')
s = sorted([timestamp, nonce, token])
# 字典排序
s = ''.join(s)
if hashlib.sha1(s.encode('utf-8')).hexdigest() == signature:
response = make_response(echostr)
return response
if __name__ == '__main__':
app.run(port=80)
写好之后就可以提交了,会显示提交成功,这样微信公众号的服务器就配置成功了。
wechatpy 是一个微信 (WeChat) 的第三方 Python SDK,用wechatpy写一个简单的自动回复程序:
import hashlib
from flask import Flask, request, make_response
from wechatpy import parse_message, create_reply
app = Flask(__name__)
app.debug = True
@app.route("/")
def hello():
return "Hello World!"
@app.route('/wechat_api/', methods=['GET', 'POST']) # 定义路由地址请与URL后的保持一致
def wechat():
global reply
if request.method == 'GET':
token = '..........'
data = request.args
signature = data.get('signature', '')
timestamp = data.get('timestamp', '')
nonce = data.get('nonce', '')
echostr = data.get('echostr', '')
s = sorted([timestamp, nonce, token])
# 字典排序
s = ''.join(s)
if hashlib.sha1(s.encode('utf-8')).hexdigest() == signature:
response = make_response(echostr)
return response
else:
msg = parse_message(request.get_data())
if msg.type == 'text':
reply = create_reply('你发送了条文字信息:' + msg.content, message=msg)
if msg.type == 'image':
reply = create_reply('你发送了条图片信息', msg)
return reply.render()
if __name__ == '__main__':
app.run(port=80)
大功告成!如果想使用更多的公众号功能,微信公众号需要认证。