微信公众号开发 腾讯云 Python

自媒体运营教程 产品运营 345

最近申请了个微信公众号,发现其提供的基础功能只有一个——向用户推送图文消息,其他功能基本都需要公众号的拥有者具备基本的开发能力。简单了解,实践后,我写下这篇教程,供大家参考。

基本步骤我是参考微信公众平台的技术文档,中间会遇到的几个问题,我会在本文中指出。

一、申请服务器并完成环境配置

我购买的是腾讯云搭载Centos7.4操作系统的服务器,当然也可以购买阿里云、百度云等服务器。但在选择操作系统时建议选择Linux系列操作系统。

购买完成后,进入控制台中的云主机就可以看到服务器的公网ip,点击右侧的登陆按钮(账号密码都在站内信里)即可登陆购买服务器的操作系统。


微信公众号开发 腾讯云 Python-第1张图片-90博客网

没有接触过Linux操作系统的人面对这样的界面可能有点害怕。一步步来,不怕不怕。


微信公众号开发 腾讯云 Python-第2张图片-90博客网

首先输入python检查一下python版本,这里腾讯云里的默认安装版本是2.7,所以之后的代码都是python2的代码。

如果安装的是python3,需要修改后面提供的代码。

绝大多数Linux操作系统都内置了Python,不幸没有Python环境的话,还是自己搜一下Linux下Python的安装,这里不再赘述。


微信公众号开发 腾讯云 Python-第3张图片-90博客网

之后依次安装web.py、libxml2、libxslt、lxml 库,命令如下:

pip install web.py
pip install libxml2
pip install libxslt
pip install lxml

如果没有pip,也自行搜一下pip的安装,这里也不再赘述。安装完成这些库后就可以开始基本的开发了。

二、测试服务器

输入命令

vim main.py

进入Linux著名的经典的极度糟心的vim编辑器编写第一个python文件。

这里简单说一下vim的操作:

  1. 进入编辑器后按i键,进入编辑模式
  2. 输入代码,或者按ctrl+shift+v粘贴代码
  3. 确认无误后,按Esc键退出编辑模式,输入:wq保存文件并退出vim

想要其他vim操作,读者可以自行搜索。

main.py的代码如下:

# -*- coding: utf-8 -*-
# filename: main.py
import web

urls = (
'/wx', 'Handle',
)

class Handle(object):
def GET(self):
return "hello, this is a handle view"

if __name__ == '__main__':
APP = web.application(urls, globals())
app.run()

编辑完成后,输入命令

python main.py 80

此时如果运行成功则不会报错,并且浏览器输入http://外网IP:80/wx会出现下图界面


微信公众号开发 腾讯云 Python-第4张图片-90博客网

如果报“socket.error: No socket could be created”错误,则有2种可能:

1、未获取root权限,输入命令

sudo python main.py 80

2、端口占用

先查询端口占用的进程

netstat -tunlp |grep 80
微信公众号开发 腾讯云 Python-第5张图片-90博客网

这里我查出22248进程占用了我的80端口,然后我把这个进程杀死,输入命令

kill -9 22248

接下来就可以顺利运行 python main.py 80了。

三、公众号Token配置

这里默认已经申请好了公众号,点击公众号的左侧最下方开发里的基本配置,然后填写服务器配置信息。


微信公众号开发 腾讯云 Python-第6张图片-90博客网

URL填写为http://公网IP/wx

令牌即为自己设置的暗号,微信平台和服务器只有对上了这个暗号才能通信

消息加解密密钥初次开发不用涉及,点击随机生成就好

消息加解密方式选择明文模式就是不管上面的那个密钥

完成配置后先不要提交,因为服务器还不知道暗号,要给服务器也配置一下。ctrl+z退出上次运行。

1、修改main.py文件,输入命令

相关影片资源迅雷下载推荐

软件测试/快来学习测试开发工程师必会的十八般武艺

因为人力成本的原因,软件测试行业对于传统手工测试越来越不友好,裁员的消息经常刷爆大家的朋友圈,但是,在如此不景气的情况下,对于测试开发工程师的需求并未减退,测试开发工程师能完成多个传统手工测试的工作。 ...

软件开发,软件测试/快来学习测试开发工程师必会的十八般武艺

vim main.py

文件修改为

# -*- coding: utf-8 -*-
# filename: main.py
import web
from handle import Handle

urls = (
'/wx', 'Handle',
)

if __name__ == '__main__':
app = web.application(urls, globals())
app.run()

2、写入handle.py文件,输入命令

vim handle.py

handle.py文件如下,注意将刚刚设置的暗号替换注释行的xxx

# -*- coding: utf-8 -*-
# filename: handle.py

import hashlib
import web

class Handle(object):
def GET(self):
try:
data = web.input()
if len(data) == 0:
return "hello, this is handle view"
signature = data.signature
timestamp = data.timestamp
nonce = data.nonce
echostr = data.echostr
token = "xxx" #你的暗号

list = [token, timestamp, nonce]
list.sort()
sha1 = hashlib.sha1()
map(sha1.update, list)
hashcode = sha1.hexdigest()
print "handle/GET func: hashcode, signature: ", hashcode, signature
if hashcode == signature:
return echostr
else:
return ""
except Exception, Argument:
return Argument

3、重启main.py,输入命令

python main.py 80

注意这里可能因为之前启动的main.py占用80端口而启动失败,可参考之前的方法,杀了占用端口的进程,再重新运行main.py。

再回到公众平台点击提交按钮,若提示”token验证失败”, 请认真检查代码或网络链接等;若token验证成功,会自动返回基本配置的主页面,点击启动按钮。此时服务器和公众号已经建立了消息连接。

四、写一个功能

这一节我们可以写一个简单的微信公众号小程序——“你说我学”。

即用户发送消息给公众号,公众号回应同样的消息。

这里先简单讲解一下原理:

用户发送给公众号的消息包含如下几个重要字段:

ToUserName:公众号

FromUserName:用户号

MsgType:标记是消息类型,Text即为文本消息

Content:消息内容

实现你说我学这个功能时,公众号回复用户的消息中,只需要将ToUserName和FromUserName倒过来,MsgType和Content原封不动的发送给用户即可。

1、服务器上修改handle.py文件

# -*- coding: utf-8 -*-
# filename: handle.py

import hashlib
import web
import lxml
import time
import os
import reply
import receive

class Handle(object):

def GET(self):
try:
data = web.input()
if len(data) == 0:
return "hello, this is handle view"
signature = data.signature
timestamp = data.timestamp
nonce = data.nonce
echostr = data.echostr
token = "xxx" #你的暗号

list = [token, timestamp, nonce]
list.sort()
sha1 = hashlib.sha1()
map(sha1.update, list)
hashcode = sha1.hexdigest()
print "handle/GET func: hashcode, signature: ", hashcode, signature
if hashcode == signature:
return echostr
else:
return ""
except Exception, Argument:
return Argument

def POST(self):
try:
webData = web.data()
print "Handle Post webdata is ", webData
recMsg = receive.parse_xml(webData)
if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text':
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
content = recMsg.content
replyMsg = reply.TextMsg(toUser, fromUser, content)
return replyMsg.send()
else:
print "暂且不处理"
return "success"
except Exception, Argment:
return Argment

2、写入receive.py文件

import xml.etree.ElementTree as ET

def parse_xml(web_data):
if len(web_data) == 0:
return None
xmlData = ET.fromstring(web_data)
msg_type = xmlData.find('MsgType').text
if msg_type == 'text':
return TextMsg(xmlData)
elif msg_type == 'image':
return ImageMsg(xmlData)

class Msg(object):
def __init__(self, xmlData):
self.ToUserName = xmlData.find('ToUserName').text
self.FromUserName = xmlData.find('FromUserName').text
self.CreateTime = xmlData.find('CreateTime').text
self.MsgType = xmlData.find('MsgType').text
self.MsgId = xmlData.find('MsgId').text

class TextMsg(Msg):
def __init__(self, xmlData):
Msg.__init__(self, xmlData)
self.Content = xmlData.find('Content').text.encode("utf-8")

class ImageMsg(Msg):
def __init__(self, xmlData):
Msg.__init__(self, xmlData)
self.PicUrl = xmlData.find('PicUrl').text
self.MediaId = xmlData.find('MediaId').text

3、写入reply.py文件

import time
class Msg(object):
def __init__(self):
pass
def send(self):
return "success"

class TextMsg(Msg):
def __init__(self, toUserName, fromUserName, content):
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['Content'] = content
def send(self):
XmlForm = """
<xml>
<ToUserName><![CDATA[{ToUserName}]]></ToUserName>
<FromUserName><![CDATA[{FromUserName}]]></FromUserName>
<CreateTime>{CreateTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{Content}]]></Content>
</xml>
"""
return XmlForm.format(**self.__dict)

class ImageMsg(Msg):
def __init__(self, toUserName, fromUserName, mediaId):
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['MediaId'] = mediaId
def send(self):
XmlForm = """
<xml>
<ToUserName><![CDATA[{ToUserName}]]></ToUserName>
<FromUserName><![CDATA[{FromUserName}]]></FromUserName>
<CreateTime>{CreateTime}</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[{MediaId}]]></MediaId>
</Image>
</xml>
"""
return XmlForm.format(**self.__dict)

4、重新运行python main.py 80,现在可以再公众号上实验这个小程序了。

五、后台运行

如果关闭了服务器的控制台,main.py文件不再运行,公众号就不具备回复用户消息的功能了,所以要在服务器中设置永久运行main.py。

这里介绍的方法是使用supervisor管理进程。

1、输入pwd查看当前目录,并记下来。

2、依次输入以下命令,安装supervisor,并生成配置文件:

pip install supervisor
echo_supervisord_conf > /etc/supervisord.conf

3、找到并修改etc/supervisord.conf文件

cd etc/
vim supervisord.conf

在该文件的最后加上

[program:myProgram]

command=python /root/main.py 80

autostart=true

stdout_logfile=/home/main.log

第一行的myProgram自己取个名字,表示你的项目就行

第二行的python /root/main.py 80表示你运行程序的命令

第三行表示自动启动,如果值为false则表示不自动启动

最后一行表示程序打印出的信息都记录在该main.log文件内,是日志文件

4、执行该配置

sudo supervisord

此时即使你关闭控制台,main.py文件也在运行了。

相关影片资源迅雷下载推荐

独立站要怎样开发客户?需找客户?

独立站逐渐成为出海大趋势,能够摆脱平台的限制、拥有更高的自主权、风险低。我们都知道平台和独立站运营模式不同:电商平台自带大量流量,买家会带着精准目标和强烈购买欲直接搜索对应的品类。但独立站的核心是“货 ...

网站建设,独立站要怎样开发客户?需找客户?

企业网站建设与开发最低只要299元起,包含域名服务器,需要的联系QQ345424724,电话15516990022,18530226930

标签: 公众号开发 微信公众号开发 腾讯云 Python

抱歉,评论功能暂时关闭!