[置顶] Django 微信开发(一)——环境搭建

时间:2023-03-09 06:07:55
[置顶] Django 微信开发(一)——环境搭建

Django 微信开发(一)——环境搭建

随着移动互联网时代的到来,微信——一个改变着我们生活的产品悄悄走近了我们的生活。我们不得不觉得自己很幸运,自己能在这个世界上遇到像QQ、微博、微信这样优秀的产品,同时,也不得不感叹这些产品的强大之处。就拿微信来说吧,我们可以文字聊天、发语音、报告位置、甚至是发视频、对讲机等功能,确实为我们平时的沟通大大降低了成本,譬如以前生日祝福等都是打电话、发短信,可在微信时代我们只要发文字或者是发一段语音就好了——省钱、简单、好用。

移动互联网的时代,你不一定需要你自己的移动APP,而且自己外包给别人做成本也比较高,小小的创业公司,就算你有了自己的移动APP,还要自己去发展用户(不同性质的公司需求不一样,举个例子而已),而且还要花大量的时间和精力在移动APP的维护上。基于不同的平台需要不同的人开发,譬如安卓版、IOS版、WP版等。因此,选择在微信上做二次开发是中小企业的不二选择。也有不少企业也有了自己的公众账号,甚至是服务号。

关于订阅号、服务号有哪些优点和缺点以及怎么使用,楼主在这里就不再赘述了,因为已经有最好的了。参考链接:http://www.zhongyaofang.cn/combat_power/weixin_jiaocheng_vol1.html 。

基于公众账号的二次开发,楼主选择的是最简单易懂的Python语言,结合Python一个轻量级的框架Django开发,操作比较简单,简单两下就能学会。由于业务发展需要,最近楼主也为自己所在的公司从事微信相关开发。因此将开发中遇到的问题及解决方案总结出来与大家,共同进步、共同成长。

  需求描述:

楼主所在的公司是一家微型金融机构,有自己的网站,现在要将网站上的一部分功能(譬如放贷、购买理财产品等)在微信端实现,这样方便微信用户的操作,顺便也从微信用户中导一份流量到自己的网站。

首先,我们来了解一下微信通信的原理。现在假设你也接到和楼主相同的需求。举个简单的流程:在微信端实现放贷的流程。                第一步,用户在微信端发送放贷请求到微信服务器,请求格式由你自己决定,只要能解析就行;

第二步,微信服务器接受到请求信息,将信息转发到你自己的网站;

第三步,在你自己的网站处理完业务逻辑,反馈结果发送到微信服务器;

第四步,微信服务器将反馈结果转发给用户。

简单四步,完成了整个通讯,详细的流程如下图:[置顶] Django 微信开发(一)——环境搭建

上图中,已经清晰的描述了通讯的原理,但是在开发过程中,我们大多都在本地,一般都是局域网,怎样才能和微信服务器实现通讯呢?当然你可以选择在服务器提供商买一台服务器,在那上面做开发。不过,细细盘算下来,成本确实有点高,所以我们要选择最简便有效的方法来解决我们的问题。在这里,楼主用到了SAE,当然你也可以用GAE, 在本地(局域网内)搭建了一个开发环境。当然,其原理还是跟上图很类似,只是稍微复杂了一点点:

第一步,用户在微信端发送放贷请求到微信服务器;

第二步,微信服务器接受到请求信息,将信息转发SAE(需要自己配置);

第三步,SAE将请求转发到指定位置(需要自己配置,还需要提供域名),我们暂且命名为“中转站”;

第四步,指定位置(“中转站”)将请求转发到你的路由;

第五步,路由通过映射转发到你的内网IP(即你的本地服务器);

第六步,你本地服务器处理完成后发送反馈到路由器;

第七步,路由器转发到指定位置(中转站);

第八步,指定位置(中转站)转发到SAE;

第九步,SAE转发到微信服务器;

第十步,微信服务器将反馈结果转发给用户。

看起来,确实有一点点复杂,不急,先看看图,且听我细细道来。[置顶] Django 微信开发(一)——环境搭建

具体思路我们已经很清楚了,现阶段,我们只需要解决各个节点中的问题即可了。

我们从简单的开始:

(1) 配置路由器映射。可能不是所有的路由器都有这个功能,其目的是为了在外网能访问你本地的IP。一般在你上网的时候,都会对应有一个IP地址,可以通过在百度中输入IP来查询你的外网IP(见下图)。由于外网IP没有给用户开放80端口(如果开放了大家的机器都可以当服务器用了),所以你需要自己打开一个端口,让外网可以访问。我在本地我指定的是9000端口,假设我现在的IP地址是192.168.0.99,外网IP经查得是116.77.5.229,那么当你本地开启网络服务后,通过访问116.77.5.229:9000地址,就可以和你本机进行通信了。[置顶] Django 微信开发(一)——环境搭建

(2) 配置“中转站”。通常,我们上网的 外网IP都是随机分配的,也就是说,我们每次上网时的外网IP都是不一样的,所以在与微信端通信的时候就比较麻烦了。在这里我们用到的"中转站"就是为了解决这一问题——让你的域名可以顺利解析到你本地的外网IP。因此,我们需要找一个DNS供应商,在这里,楼主找到了免费的DNSPod:https://www.dnspod.cn/ ,不过需要你在这上面注册一个用户,然后将你在域名提供商购买的域名配置为DNSPod的DNS地址,如图:[置顶] Django 微信开发(一)——环境搭建

除此之外,我们还要配置一个子域名如:wx.xxxx.com(xxxx是你的域名),记录值那一栏就是你外网的IP,但是这样你每次都要查询你的外网IP,然后将IP更改过来来。是不是很繁琐?有没有一劳永逸的办法?

答案是:当然有。楼主整来了下面一段代码,将你在DNSPod上的用户名和密码写入,在本地配上Python环境就可以使用喔:

#!/usr/bin/env python
# coding: utf-8 import httplib, urllib, urllib2
import time
import sys,os
import re
import json username = 'yima1006@qq.com' #账号
password = 'password' #密码
format = 'json' domain = [u'wx.xxxxx.com'] #要解析的域名 def get_domain_info(domain):
domain_split = domain.split('.')
domain_split_len = len(domain_split)
maindomain = domain_split[domain_split_len - 2] + '.' + domain_split[domain_split_len - 1]
return maindomain,domain params = {'login_email':username,'login_password':password,'format':format} def request(action, params, method = 'POST'):
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
conn = httplib.HTTPSConnection("dnsapi.cn")
conn.request(method, '/' + action, urllib.urlencode(params), headers)
response = conn.getresponse()
data = response.read()
conn.close()
if response.status == 200:
return data
else:
return None def get_my_domain_id():
data = request('Domain.List',params)
data = json.loads(data)
domainlist = data.get('domains')
domaninfo = {}
for d in domainlist:
domaninfo[d.get('name')] = d.get('id')
return domaninfo def get_my_domain_record_id(domain_id):
params['domain_id'] = domain_id
data = request('Record.List',params)
data = json.loads(data)
if data.get('code') == '10':
return None
domainname = data.get('domain').get('name')
record_list = data.get('records')
record = {}
for r in record_list:
if r.get('type') == 'A':
key = r.get('name') != '@' and r.get('name') + '.' + domainname or domainname
record[key] = {'id':r.get('id'),'value':r.get('value')}
print record
return record def changerecord(domain,domain_id,record_id,ip):
params['domain_id'] = domain_id
params['record_id'] = record_id
params['record_type'] = 'A'
params['record_line'] = '默认'
params['sub_domain'] = domain
params['ttl'] = 600
params['value'] = ip
data = request('Record.Modify',params) def getip():
url = 'http://iframe.ip138.com/ic.asp'
response = urllib2.urlopen(url)
text = response.read()
ip = re.findall(r'\d+.\d+.\d+.\d+', text)
print '外网IP:%s'%ip[0]
return ip[0] or None def updatedomaininfo(domain):
m,sub_m = get_domain_info(domain)
domain_id = my_domain_id_list.get(m)
record_list = get_my_domain_record_id(domain_id)
if record_list == None:
return None
rocord_info = record_list.get(sub_m)
record_ip = rocord_info.get('value')
record_id = rocord_info.get('id')
return sub_m,record_ip,record_id,domain_id if __name__ == '__main__':
my_domain_id_list = get_my_domain_id()
try:
for dm in domain:
domaindata = updatedomaininfo(dm)
if domaindata == None:
continue
dnsdomain,dnsdmainip,record_id,domain_id = domaindata
domain_name = dnsdomain.split('.')[0]
ip = getip()
if ip == dnsdmainip:
continue
else:
changerecord(domain_name,domain_id,record_id,ip)
except:
pass

这样,通过访问http://wx.xxxx.com:9000端口就能找到你本地的服务器了。

(3)配置SAE应用。在SAE上,我们只需要做一个简单的代理就行,即将微信服务器转发过来的请求按照原来的方式转发到你的“中转站”就好了。在这里,我们用到了一个Python机器轻量级的web框架——web.py。我们可以在SAE上直接创建一个Python项目,然后在index.wsgi文件中贴如如下一段代码就行了。

#/usr/bin/python
#coding:utf-8 import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import web
import urllib2
try:
import sae
except:
pass urls = (
'/weixin/?', 'weixin',
) web.config.debug = True
app = web.application(urls, globals()) class weixin:
def GET(self):
""" GET 请求转发"""
url = "http://wx.xxxx.com:9000/weixin/?" # 转发地址,与你的路由器端口映射
d = web.input() # 读取参数
data = []
for i in d:
data.append(i + '=' + d[i])
url = url + '&'.join(data) # 拼接参数
req = urllib2.Request(url=url)
res = urllib2.urlopen(req )
return res.read() def POST(self):
""" POST请求转发 """
data = web.data() # 转发参数
url = "http://wx.xxxx.com:9000/weixin/?" # 转发地址,与你的路由器端口映射
req = urllib2.Request(url=url, data=data)
res = urllib2.urlopen(req, timeout=10 )
return res.read() if __name__ =="__main__":
app.run()
else:
try:
app = web.application(urls, globals()).wsgifunc()
application = sae.create_wsgi_app(app)
#application = sae.create_wsgi_app(ShellMiddleware(app))
except:
pass

这样,我们本地的开发环境搭建已经基本完成,只需要稍作配置就可以开发了。

感谢您的关注,更多详细,请听下回为您分解。