Linux迷+Python粉 - 微信https://blog.pythonwood.com/2017-12-29T15:00:00+08:00个案分析:20800元的微信小程序抢注骗局揭秘2017-12-29T15:00:00+08:002017-12-29T15:00:00+08:00pythonwoodtag:blog.pythonwood.com,2017-12-29:/2017/12/个案分析:20800元的微信小程序抢注骗局揭秘/<p>2017年12月份,我身边一位做实体母婴商品店的老板陷入了一场微信小程序“骗局”,以每个小程序20800的价格投资了小程序,我一开始以也没发现很不妥,直到后来老板再次被忽悠买多了几个小程序才醒悟是这样一场骗局。</p>
<h3 id="_1">过程<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
<ol>
<li>骗子以展望小程序未来,小程序像域名那样具有唯一性,有品牌推广功能等等为噱头,诱骗店主购买小程序20800元。</li>
<li>
<p>半年后,四川一家野技公司加了店主微信,表示他的小程序名字非常唯一,价值高,有家天津科技公司愿意买,然后故意任由店主出价。最后谈到150万转让费。期间制造各种问题拖延时间,店主也认为升值快 …</p></li></ol><p>2017年12月份,我身边一位做实体母婴商品店的老板陷入了一场微信小程序“骗局”,以每个小程序20800的价格投资了小程序,我一开始以也没发现很不妥,直到后来老板再次被忽悠买多了几个小程序才醒悟是这样一场骗局。</p>
<h3 id="_1">过程<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
<ol>
<li>骗子以展望小程序未来,小程序像域名那样具有唯一性,有品牌推广功能等等为噱头,诱骗店主购买小程序20800元。</li>
<li>
<p>半年后,四川一家野技公司加了店主微信,表示他的小程序名字非常唯一,价值高,有家天津科技公司愿意买,然后故意任由店主出价。最后谈到150万转让费。期间制造各种问题拖延时间,店主也认为升值快,担心卖早了,不想早早答应,“配合”拖延。</p>
</li>
<li>
<p>再有其他2家异地公司谈另一种合作模式,一切成本由科技公司出,有利润后,店主和公司按8:2分成。为增加信任,同时给出了一篇四海皆准的操作方案稿,并且互怼竞争方说自己公司才比较靠谱。</p>
</li>
<li>我开始介入,发现小程序可登录可运行,前台后台用户体验都极差,并有不能写收货地址等明显bug。但因为反馈后当日下午就修复了问题,就觉得这家公司还是靠谱的。我甚至还觉得店主可能真的捡到金了。毕竟在互联网工作,见过些大起大落的科技浪潮。风口之中,猪也能飞。</li>
<li>后来店主被忽悠,再入手2个20800元的小程序,签完文件交了钱才和我说。我终于才想清楚整件事情。——一边虚高价销售抢注和维护小程序的“终身服务”,一边装作有意收购出更离谱的高价造成店主认为小程序极具投资价值的幻觉。然后骗子让店主多买几个来挣更多钱。 因没有互联网经验,实体店主在被忽悠下爽口地多买几个。</li>
<li>认清这个行骗模式之后劝醒了店主,店主后来收回合约和钱,只损失了2000元。至于之前就有那个小程序,他表示就算了。此事至此结束。</li>
</ol>
<p><img alt="可疑公司1" height="50%" src="https://blog.pythonwood.com/uploads/2017/可疑公司1.jpg" title="可疑公司1" width="20%">
<img alt="可疑公司2" height="50%" src="https://blog.pythonwood.com/uploads/2017/可疑公司2.jpg" title="可疑公司2" width="20%">
<img alt="可疑公司3" height="50%" src="https://blog.pythonwood.com/uploads/2017/可疑公司3.jpg" title="可疑公司3" width="20%">
<img alt="可疑公司合同" height="50%" src="https://blog.pythonwood.com/uploads/2017/可疑公司合同.jpg" title="可疑公司合同" width="20%"> </p>
<h3 id="_2">证据难点<a class="headerlink" href="#_2" title="Permanent link">¶</a></h3>
<p>这个产品是一个能运行,能使用,能交易的空壳,除此之外毫无价值。
虽然明知那些小程序的劣质功能只值两、三千,卖了20800给实体店主,但是骗子可以咬定这个壳程序就值这个价。 互联网虚拟产品成本核算难问题。让你无法判定次品高卖这个事实。所以,这是一次高级的骗局,虽然能识破,但维权投诉没有用。</p>
<p>最近接触股市,中国股市的本质是不是类似呢?
再比如比特币最近大起大落…… 大伪若真。假作真时假亦真。</p>
<h3 id="_3">参考<a class="headerlink" href="#_3" title="Permanent link">¶</a></h3>
<p>假冒腾讯公司1.98万卖小程序,各大小老板为何纷纷被骗? http://www.newbelink.com/article/31911.html</p>
<p>注意微信小程序骗局 https://tieba.baidu.com/p/5249331035</p>
<p>警惕!北海出现“1.98万抢注小程序”骗局!已有人被骗惨,都要注意… http://www.sohu.com/a/203976441_185101</p>微信开发python+django两个月的成功经历,django是个好框架!2014-06-28T20:12:00+08:002014-06-28T20:12:00+08:00pythonwoodtag:blog.pythonwood.com,2014-06-28:/2014/06/微信开发python+django两个月的成功经历,django是个好框架!/<h3 id="_1">时间:大三<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
<p>上学期没有用微信内置浏览器而纯对话开发,坑了自己好一下。</p>
<p>下学期选错bottle框架,以为轻量好,谁知开发中什么都自己来很痛苦。</p>
<p>选对了框架django,终于在大三最后的个把月里写出了里程碑式的现在这个微信端,自己都感动到,作为我大三一年web开发的终结吧。</p>
<p>亮点1:自带后台管理</p>
<p>亮点2:后台权限管理</p>
<p>亮点3:微信回复规则设置去代码化,图形界面。</p>
<p>亮点4:一平台多网店 …</p><h3 id="_1">时间:大三<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
<p>上学期没有用微信内置浏览器而纯对话开发,坑了自己好一下。</p>
<p>下学期选错bottle框架,以为轻量好,谁知开发中什么都自己来很痛苦。</p>
<p>选对了框架django,终于在大三最后的个把月里写出了里程碑式的现在这个微信端,自己都感动到,作为我大三一年web开发的终结吧。</p>
<p>亮点1:自带后台管理</p>
<p>亮点2:后台权限管理</p>
<p>亮点3:微信回复规则设置去代码化,图形界面。</p>
<p>亮点4:一平台多网店</p>
<p>亮点5:图片自动缩略成200*300px大小(使用了七牛空间)</p>
<p>亮点6:gzip压缩,网络流量为原来33%左右。<span class="caps">SAE</span>中Gzip压缩设置</p>
<p>亮点7:保存接受的所以文本消息,记录永存!</p>
<p>亮点8:购买者可查看历史订单,购买总额等。</p>
<p>亮点9:后台可查看用户下单总额,最近下单时间等等。</p>
<p>亮点10:商店信息,商品信息均在后台直接修改。</p>
<p>亮点11:平台创始人可强制商店下线。</p>
<p>技巧:微信规则不匹配时不能回复吗?不是,规则包含空字符总能匹配任意文本,请看下面的微信规则截图。</p>
<h3 id="_2">后台<a class="headerlink" href="#_2" title="Permanent link">¶</a></h3>
<p>选择botlle框架,自己写sql,便学边用,很痛苦的换了20天作出来了微信<a href="http://2.aozhouwine.sinaapp.com/buy.html?openid=abcdefgabcdefgabcdefgabcdefg" title="顾客演示入口地址">第一版</a>。这版其实很简陋,但其给我的经验很重要。演示地址:<a href="http://2.aozhouwine.sinaapp.com/buy.html?openid=abcdefgabcdefgabcdefgabcdefg" title="顾客演示入口地址">点击入口</a>。</p>
<p>抛弃bottle,选择django,后来证明我的选择是对的,虽然学习坡度比较大,但是其框架本身带来的效率和效益却是学习框架本身的好几倍。我喜欢它的自带后台管理,和后台权限管理,更喜欢它的<span class="caps">ORM</span>,省去很多sql的事情,比如sql语句编写,sql防注问题,sql迁移方便等等。这次用上了这三大功能,另外还巧用django的模板渲染实现微信回复功能,但这不是django特有。</p>
<p>微信已经实现了多店功能。这也是当初我为什么坚定选择django,因为django的一project多app的架构刚好契合这个一平台多店铺的想法。后来我学scrapy框架,发现也是一project多app,方便不少。同时说明一project多app是先进的,是趋势之一。</p>
<h3 id="_3">前台<a class="headerlink" href="#_3" title="Permanent link">¶</a></h3>
<p>我比较喜欢后端的开发,前端的我就修改已有好的前端代码,参考了微信公众号“果然美”,“微果大爱”,“华农果满堂”,“微盟”,“乐外卖”等前端设计。技术上使用html5+css3。</p>
<p>现在平台上有果色天香和澳洲红酒两个店铺</p>
<p><img alt="平台上有果色天香和澳洲红酒两个店铺1.png" height="50%" src="https://blog.pythonwood.com/static/img/平台上有果色天香和澳洲红酒两个店铺1.png" title="1" width="30%">
<img alt="平台上有果色天香和澳洲红酒两个店铺2.jpg" height="50%" src="https://blog.pythonwood.com/static/img/平台上有果色天香和澳洲红酒两个店铺2.jpg" title="2" width="30%">
<img alt="平台上有果色天香和澳洲红酒两个店铺3.jpg" height="50%" src="https://blog.pythonwood.com/static/img/平台上有果色天香和澳洲红酒两个店铺3.jpg" title="3" width="30%"></p>
<h3 id="_4">代码统计<a class="headerlink" href="#_4" title="Permanent link">¶</a></h3>
<p>使用linux shell统计 </p>
<p>合理版 cat $(find . -name “<em>.py” -or -name “</em>.yaml” -or -name “*.rst” -or -name “sell_detail.html”) | wc | sed “1i static:\nlines | words | bytes” </p>
<p><img alt="tu" src="https://blog.pythonwood.com/static/img/代码统计1.png" title="1"></p>
<p>纯净版 cat $(find . -path “./guosetianxiang” -prune -or -name “<em>.py” -or -name “</em>.yaml” -or -name “*.rst” -or -name “sell_detail.html”) | wc | sed “1i static:\nlines | words | bytes” </p>
<p><img alt="tu" src="https://blog.pythonwood.com/static/img/代码统计2.png" title="2"></p>
<p>完全版 cat $(find . -name “<em>.py” -or -name “</em>.yaml” -or -name “<em>.rst” -or -name “</em>.html”) | wc | sed “1i static:\nlines | words | bytes” </p>
<p><img alt="tu" src="https://blog.pythonwood.com/static/img/代码统计3.png" title="3"></p>
<h3 id="_5">前端展示:感谢前人成果!<a class="headerlink" href="#_5" title="Permanent link">¶</a></h3>
<p><img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/前端展示1.png" title="1" width="40%">
<img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/前端展示2.png" title="2" width="40%"></p>
<h3 id="_6">=============================后台是亮点=============================<a class="headerlink" href="#_6" title="Permanent link">¶</a></h3>
<p>后台首页</p>
<p><img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/后台首页.png" title="1" width="90%"></p>
<p>微信回复规则,使用模板渲染自定义变量!</p>
<p><img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/微信回复规则,使用模板渲染自定义变量.png" title="1" width="90%"></p>
<p>功能代码:</p>
<p><img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/功能代码.png" title="1" width="90%"></p>
<p>微信用户</p>
<p><img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/微信用户.png" title="1" width="90%"></p>
<p>订单截图</p>
<p><img alt="tu" height="50%" src="https://blog.pythonwood.com/static/img/订单截图.png" title="1" width="90%"></p>
<h3 id="django">看到这里,你是否也认为django是个好框架呢?<a class="headerlink" href="#django" title="Permanent link">¶</a></h3>
<p>在新浪云上运行得还好,不算慢,请那些嫌弃django臃肿庞大,速度慢的人,不要再误导他人,这就好像那些说python慢的人一样,我至今没有实践证明出过慢在哪。</p>
<p>django是python作者本身都很喜欢的框架,又是那么多商用网站的框架,经得其考验。</p>
<p>如果可以,当然希望你可以作出一个比django更好的框架,可是至少现在还不大可能。python的django和ruby的rails都得经过时间的考验。我相信 django 是经得住考验的,正如我相信python一样。</p>
<h3 id="_7">附上 增加微店步骤(澳洲红酒为例)<a class="headerlink" href="#_7" title="Permanent link">¶</a></h3>
<p>复制guosetianxiang 改名 aozhouwine</p>
<p>修改setting.py 安装app ‘aozhouwine’</p>
<p>访问/syncdb-online完成数据库同步</p>
<p>根app的url.py 加入两行:</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">aozhouwine</span>
<span class="o">...</span>
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^aozhouwine/'</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s1">'aozhouwine.urls'</span><span class="p">)),</span>
</pre></div>
<p>admin管理,weixinshop应用商店表中增加一条,并增加账户给商店所有者A,然后授权。</p>
<p>A在自己的应用商店信息表中增加一条记录,(token在此设置)。</p>
<p>微信开发者url: /aozhouwine/weixin/ token为之前设置的。</p>
<p>访问/aozhouwine/sync_shopinfo完成商店同步。</p>
<p>A增加消息,回复规则表中的记录。</p>
<p>A上架商品。</p>
<p>依然涉及少量代码操作,以及有一点繁琐。</p>微信公众平台开发(免费云BAE+高效优雅的Python+网站开放的API)2013-10-16T23:44:00+08:002017-11-27T22:12:00+08:00pythonwoodtag:blog.pythonwood.com,2013-10-16:/2013/10/微信公众平台开发(免费云BAE+高效优雅的Python+网站开放的API)/<p>虽然校园App是个我认为的绝对的好主意,但最近有个也不错的营销+开发的模式出现:微信平台+固定域名服务器。</p>
<p>微信公众平台的运行模式不外两个:</p>
<p>一、机器人模式或称转发模式,将说话内容转发到服务器上完成,拿服务器的回复再一次转发,就完成一次问答谈话。</p>
<p>二、人控模式,一个自然人登陆公众平台上,能直接接触到所有关注者,与之交互,这一定也是最累的。</p>
<p>微信公众平台若是服务号,用来做微网站,省去了登录认证过程 …</p><p>虽然校园App是个我认为的绝对的好主意,但最近有个也不错的营销+开发的模式出现:微信平台+固定域名服务器。</p>
<p>微信公众平台的运行模式不外两个:</p>
<p>一、机器人模式或称转发模式,将说话内容转发到服务器上完成,拿服务器的回复再一次转发,就完成一次问答谈话。</p>
<p>二、人控模式,一个自然人登陆公众平台上,能直接接触到所有关注者,与之交互,这一定也是最累的。</p>
<p>微信公众平台若是服务号,用来做微网站,省去了登录认证过程。但说白了就是微信定制版的微网站。这我一学期后才搞懂,如果早些弄懂就不会做那么多无用功。</p>
<p>微信公众平台须有正面头像+身份证的照片来实名认证,非常严格。顺便一说,微信公众平台官方说法是偏支持大企而非个人。</p>
<p>服务器(准确的说只是一个引擎)有新浪云<span class="caps">SAE</span>,百度云<span class="caps">BAE</span>,阿里云<span class="caps">AAE</span>。</p>
<p><span class="caps">SAE</span>最早,但使用云豆消费,注册只送500个。到现在,<span class="caps">BAE</span>允许创建10个应用而不用实名认证,<span class="caps">SAE</span>是需实名认证的。还有<span class="caps">BAE</span>比<span class="caps">SAE</span>强的就是支持git,虽然两者都支持svn,非常合时,刚好我学习git中,我果断选择<span class="caps">BAE</span>。云上建的每个应用可有20个版本,但任一个版都可以并且唯一上线。<span class="caps">AAE</span>(阿里云)一直不支持python,很让人失望。</p>
<h3 id="_1">第一阶段:入门——轻轻走过飘过。<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
<p>下面是用数天时间借鉴前人成果Kingson的《<a href="http://kingson.org/?p=259" title>一个用Python和Bottle实现基于微信公众平台<span class="caps">API</span>和<span class="caps">SAE</span>查询豆瓣电影的简单应用</a>》开发的。</p>
<p>这个例子非常适合在用Python的开发人员。经过一番狠狠的折腾,我还弄懂了其它问题:云的概念、OAuth、token、微信<span class="caps">API</span>调用,网站<span class="caps">API</span>调用、python等,百度谷歌都会有答案。</p>
<p>还有很多像微信<span class="caps">API</span>通信认证(话说竞然用xml而不用json通信,不过这是取舍问题,无可厚非),python web框架,git对接云服务器……用了我许多时间。过程曲折复杂,看起来只是转移一下云平台,但实名认证,开发者域名的认证等浪费了我很多时间,因为没经验,很多各种问题都撞上了,尤其是我这种粗心大意,心眼碗粗的人,整个过程实在不算顺利,但我相信别人都会比我顺利,因为我连最低级的错都犯了。不多说,贴上关键代码代码。</p>
<p>下载地址:http://pan.baidu.com/s/1d1g3l</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="ch">#! /usr/bin/env python</span>
<span class="c1"># coding=utf-8</span>
<span class="n">__author__</span> <span class="o">=</span> <span class="s1">'jszhou'</span>
<span class="kn">from</span> <span class="nn">bottle</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">xml.etree.ElementTree</span> <span class="kn">as</span> <span class="nn">ET</span>
<span class="kn">import</span> <span class="nn">urllib2</span>
<span class="c1"># import requests</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">Bottle</span><span class="p">()</span>
<span class="sd">"""</span>
<span class="sd">Change Log:</span>
<span class="sd">03-04--03-08 完成微信API+Python自动回复代码雏形,可以通过电影ID查询电影信息,以Text形式返回给用户电影</span>
<span class="sd">Title和电影summary</span>
<span class="sd"># 03-11 完成通过电影名称查询并返回图文格式的数据</span>
<span class="sd"># 03-13 1.增加给新关注的用户自动返回“欢迎关注豆瓣电影,输入电影名称即可快速查询电影讯息哦!”信息的功能</span>
<span class="sd"> 2.完善注释信息</span>
<span class="sd">关于本地调试问题:</span>
<span class="sd">微信没有提供本地调试功能,给用户造成不小的麻烦。</span>
<span class="sd">打开Bottle的Debug功能,在本地运行自己的代码(启动Server),使用Chrome或Firefox上的Advanced Rest Client插件来模拟微信服务器向自己的应用发送请求,</span>
<span class="sd">这样就可以看到详细的报错信息,方便开发者定位修复问题,其相当于,自己的应用是SAE,而Advanced Rest Client模拟的是新微信客户端和微信服务器。</span>
<span class="sd">也有同学自己写脚本,模拟微信服务器发送数据,这也是同样的道理。</span>
<span class="sd">遗留问题:</span>
<span class="sd">1.从豆瓣拿到的海报图片都是竖向的,而微信中显示的是横向的,所以在微信看图片就被裁了一节,不过还好能看,</span>
<span class="sd"> 如何能完整显示海报图片,有待进一步research;</span>
<span class="sd">2.现在的通过电影名称返回的结果,实际上是拿的豆瓣返回的第一条数据,这样就有可能不准确,如何精确匹配用户的</span>
<span class="sd"> 查询条件,也还需要进一步研究。</span>
<span class="sd">"""</span>
<span class="nd">@app.get</span><span class="p">(</span><span class="s2">"/"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">checkSignature</span><span class="p">():</span>
<span class="sd">"""</span>
<span class="sd"> 这里是用来做接口验证的,从微信Server请求的URL中拿到“signature”,“timestamp”,"nonce"和“echostr”,</span>
<span class="sd"> 然后再将token, timestamp, nonce三个排序并进行Sha1计算,并将计算结果和拿到的signature进行比较,</span>
<span class="sd"> 如果相等,就说明验证通过。</span>
<span class="sd"> 话说微信的这个验证做的很渣,因为只要把echostr返回去,就能通过验证,这也就造成我看到一个Blog中,</span>
<span class="sd"> 验证那儿只返回了一个echostr,而纳闷了半天。</span>
<span class="sd"> 附微信Server请求的Url示例:http://yoursaeappid.sinaapp.com//?signature=730e3111ed7303fef52513c8733b431a0f933c7c</span>
<span class="sd">&echostr=5853059253416844429&timestamp=1362713741&nonce=1362771581</span>
<span class="sd"> """</span>
<span class="n">token</span> <span class="o">=</span> <span class="s2">""</span> <span class="c1"># 你在微信公众平台上设置的TOKEN</span>
<span class="n">signature</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'signature'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="c1"># 拼写不对害死人那,把signature写成singnature,直接导致怎么也认证不成功</span>
<span class="n">timestamp</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'timestamp'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="n">nonce</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'nonce'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="n">echostr</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'echostr'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="n">tmpList</span> <span class="o">=</span> <span class="p">[</span><span class="n">token</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">,</span> <span class="n">nonce</span><span class="p">]</span>
<span class="n">tmpList</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="n">tmpstr</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s%s%s</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">tmpList</span><span class="p">)</span>
<span class="n">hashstr</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">tmpstr</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">if</span> <span class="n">hashstr</span> <span class="o">==</span> <span class="n">signature</span><span class="p">:</span>
<span class="k">return</span> <span class="n">echostr</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">"wws:indentify error"</span>
<span class="k">def</span> <span class="nf">parse_msg</span><span class="p">():</span>
<span class="sd">"""</span>
<span class="sd"> 这里是用来解析微信Server Post过来的XML数据的,取出各字段对应的值,以备后面的代码调用,也可用lxml等模块。</span>
<span class="sd"> """</span>
<span class="n">recvmsg</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="c1"># 严重卡壳的地方,最后还是在Stack OverFlow上找到了答案</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">fromstring</span><span class="p">(</span><span class="n">recvmsg</span><span class="p">)</span>
<span class="n">msg</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">root</span><span class="p">:</span>
<span class="n">msg</span><span class="p">[</span><span class="n">child</span><span class="o">.</span><span class="n">tag</span><span class="p">]</span> <span class="o">=</span> <span class="n">child</span><span class="o">.</span><span class="n">text</span>
<span class="k">return</span> <span class="n">msg</span>
<span class="k">def</span> <span class="nf">query_movie_info</span><span class="p">():</span>
<span class="sd">"""</span>
<span class="sd"> 这里使用豆瓣的电影search API,通过关键字查询电影信息,这里的关键点是,一是关键字取XML中的Content值,</span>
<span class="sd"> 二是如果Content中存在汉字,就需要先转码,才能进行请求</span>
<span class="sd"> """</span>
<span class="n">movieurlbase</span> <span class="o">=</span> <span class="s2">"http://api.douban.com/v2/movie/search"</span>
<span class="n">DOUBAN_APIKEY</span> <span class="o">=</span> <span class="s2">""</span> <span class="c1"># 这里需要填写你自己在豆瓣上申请的应用的APIKEY</span>
<span class="n">movieinfo</span> <span class="o">=</span> <span class="n">parse_msg</span><span class="p">()</span>
<span class="n">searchkeys</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">quote</span><span class="p">(</span><span class="n">movieinfo</span><span class="p">[</span><span class="s2">"Content"</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span> <span class="c1"># 如果Content中存在汉字,就需要先转码,才能进行请求</span>
<span class="n">url</span> <span class="o">=</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">?q=</span><span class="si">%s</span><span class="s1">&apikey=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">movieurlbase</span><span class="p">,</span> <span class="n">searchkeys</span><span class="p">,</span> <span class="n">DOUBAN_APIKEY</span><span class="p">)</span>
<span class="c1"># return "<p>{'url': %s}</p>" % url</span>
<span class="c1"># url = '%s%s?apikey=%s' % (movieurlbase, id["Content"], DOUBAN_APIKEY)</span>
<span class="c1"># resp = requests.get(url=url, headers=header)</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="n">movie</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="c1"># return "<p>{'movie': %s}</p>" % movie</span>
<span class="c1"># info = movie["subjects"][0]["title"] + movie["subjects"][0]["alt"]</span>
<span class="c1"># info = movie['title'] + ': ' + ''.join(movie['summary'])</span>
<span class="k">return</span> <span class="n">movie</span>
<span class="c1"># return info</span>
<span class="k">def</span> <span class="nf">query_movie_details</span><span class="p">():</span>
<span class="sd">"""</span>
<span class="sd"> 这里使用豆瓣的电影subject API,通过在query_movie_info()中拿到的电影ID,来获取电影的summary。</span>
<span class="sd"> """</span>
<span class="n">movieurlbase</span> <span class="o">=</span> <span class="s2">"http://api.douban.com/v2/movie/subject/"</span>
<span class="n">DOUBAN_APIKEY</span> <span class="o">=</span> <span class="s2">""</span> <span class="c1"># 这里需要填写你自己在豆瓣上申请的应用的APIKEY</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">query_movie_info</span><span class="p">()</span>
<span class="n">url</span> <span class="o">=</span> <span class="s1">'</span><span class="si">%s%s</span><span class="s1">?apikey=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">movieurlbase</span><span class="p">,</span> <span class="nb">id</span><span class="p">[</span><span class="s2">"subjects"</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">"id"</span><span class="p">],</span> <span class="n">DOUBAN_APIKEY</span><span class="p">)</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="n">description</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">description</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">description</span><span class="p">[</span><span class="s1">'summary'</span><span class="p">])</span>
<span class="k">return</span> <span class="n">description</span>
<span class="nd">@app.post</span><span class="p">(</span><span class="s2">"/"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">response_msg</span><span class="p">():</span>
<span class="sd">"""</span>
<span class="sd"> 这里是响应微信Server的请求,并返回数据的主函数,判断Content内容,如果是“Hello2BizUser”,就</span>
<span class="sd"> 表明是一个新注册用户,调用纯文本格式返回,如果是其他的内容就组织数据以图文格式返回。</span>
<span class="sd"> 基本思路:</span>
<span class="sd"> # 拿到Post过来的数据</span>
<span class="sd"> # 分析数据(拿到FromUserName、ToUserName、CreateTime、MsgType和content)</span>
<span class="sd"> # 构造回复信息(将你组织好的content返回给用户)</span>
<span class="sd"> """</span>
<span class="c1">#拿到并解析数据</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">parse_msg</span><span class="p">()</span>
<span class="c1">#设置返回数据模板</span>
<span class="c1">#纯文本格式</span>
<span class="n">textTpl</span> <span class="o">=</span> <span class="s2">"""<xml></span>
<span class="s2"> <ToUserName><![CDATA[</span><span class="si">%s</span><span class="s2">]]></ToUserName></span>
<span class="s2"> <FromUserName><![CDATA[</span><span class="si">%s</span><span class="s2">]]></FromUserName></span>
<span class="s2"> <CreateTime></span><span class="si">%s</span><span class="s2"></CreateTime></span>
<span class="s2"> <MsgType><![CDATA[</span><span class="si">%s</span><span class="s2">]]></MsgType></span>
<span class="s2"> <Content><![CDATA[</span><span class="si">%s</span><span class="s2">]]></Content></span>
<span class="s2"> <FuncFlag>0</FuncFlag></span>
<span class="s2"> </xml>"""</span>
<span class="c1">#图文格式</span>
<span class="n">pictextTpl</span> <span class="o">=</span> <span class="s2">"""<xml></span>
<span class="s2"> <ToUserName><![CDATA[</span><span class="si">%s</span><span class="s2">]]></ToUserName></span>
<span class="s2"> <FromUserName><![CDATA[</span><span class="si">%s</span><span class="s2">]]></FromUserName></span>
<span class="s2"> <CreateTime></span><span class="si">%s</span><span class="s2"></CreateTime></span>
<span class="s2"> <MsgType><![CDATA[news]]></MsgType></span>
<span class="s2"> <ArticleCount>1</ArticleCount></span>
<span class="s2"> <Articles></span>
<span class="s2"> <item></span>
<span class="s2"> <Title><![CDATA[</span><span class="si">%s</span><span class="s2">]]></Title></span>
<span class="s2"> <Description><![CDATA[</span><span class="si">%s</span><span class="s2">]]></Description></span>
<span class="s2"> <PicUrl><![CDATA[</span><span class="si">%s</span><span class="s2">]]></PicUrl></span>
<span class="s2"> <Url><![CDATA[</span><span class="si">%s</span><span class="s2">]]></Url></span>
<span class="s2"> </item></span>
<span class="s2"> </Articles></span>
<span class="s2"> <FuncFlag>1</FuncFlag></span>
<span class="s2"> </xml> """</span>
<span class="c1">#判断Content内容,如果等于"Hello2BizUser",表明是一个新关注用户,如果不是,就返回电影标题,电影简介</span>
<span class="c1">#和电影海报组成的图文信息</span>
<span class="k">if</span> <span class="n">msg</span><span class="p">[</span><span class="s2">"Content"</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"Hello2BizUser"</span><span class="p">:</span>
<span class="n">echostr</span> <span class="o">=</span> <span class="n">textTpl</span> <span class="o">%</span> <span class="p">(</span>
<span class="n">msg</span><span class="p">[</span><span class="s1">'FromUserName'</span><span class="p">],</span> <span class="n">msg</span><span class="p">[</span><span class="s1">'ToUserName'</span><span class="p">],</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())),</span> <span class="n">msg</span><span class="p">[</span><span class="s1">'MsgType'</span><span class="p">],</span>
<span class="sa">u</span><span class="s2">"欢迎关注豆瓣电影,输入电影名称即可快速查询电影讯息哦!"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">echostr</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">Content</span> <span class="o">=</span> <span class="n">query_movie_info</span><span class="p">()</span>
<span class="n">description</span> <span class="o">=</span> <span class="n">query_movie_details</span><span class="p">()</span>
<span class="n">echostr</span> <span class="o">=</span> <span class="n">pictextTpl</span> <span class="o">%</span> <span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="s1">'FromUserName'</span><span class="p">],</span> <span class="n">msg</span><span class="p">[</span><span class="s1">'ToUserName'</span><span class="p">],</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())),</span>
<span class="n">Content</span><span class="p">[</span><span class="s2">"subjects"</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">"title"</span><span class="p">],</span> <span class="n">description</span><span class="p">,</span>
<span class="n">Content</span><span class="p">[</span><span class="s2">"subjects"</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">"images"</span><span class="p">][</span><span class="s2">"large"</span><span class="p">],</span> <span class="n">Content</span><span class="p">[</span><span class="s2">"subjects"</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">"alt"</span><span class="p">])</span>
<span class="k">return</span> <span class="n">echostr</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="c1"># Interactive mode</span>
<span class="n">debug</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="n">run</span><span class="p">(</span><span class="n">app</span><span class="p">,</span><span class="n">host</span><span class="o">=</span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">8080</span><span class="p">,</span> <span class="n">reloader</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Mod WSGI launch</span>
<span class="c1"># import sae</span>
<span class="c1"># debug(True)</span>
<span class="c1"># os.chdir(os.path.dirname(__file__))</span>
<span class="c1"># app = default_app()</span>
<span class="c1"># application = sae.create_wsgi_app(app)</span>
<span class="c1">#################################################</span>
<span class="c1">#os.chdir(os.path.dirname(__file__))#Forbidden to access</span>
<span class="kn">from</span> <span class="nn">bae.core.wsgi</span> <span class="kn">import</span> <span class="n">WSGIApplication</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">WSGIApplication</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>注:代码中用json.dumps会更好。 后注:此注不对。</p>
<h2 id="httpwwwcnblogscommchinatage5beaee4bfa1e585ace4bc97python">深入阶段,将http://www.cnblogs.com/mchina/tag/%E5%<span class="caps">BE</span>%<span class="caps">AE</span>%E4%<span class="caps">BF</span>%A1%E5%85%<span class="caps">AC</span>%E4%<span class="caps">BC</span>%97/里的功能用python实现之。<a class="headerlink" href="#httpwwwcnblogscommchinatage5beaee4bfa1e585ace4bc97python" title="Permanent link">¶</a></h2>
<p>……</p>
<p>本代码需要与bottle.py一并上传到服务器空间。</p>
<p>附上一些特别信息:</p>
<p>微信开发调试小工具下载:http://www.cnblogs.com/linkbiz/archive/2013/05/16/3080306.html</p>
<p>本人微信公众号pythonwoodpub, 开发项目澳洲红酒微信服务号,</p>
<p><img alt="本人微信公众号pythonwoodpub.jpg" height="50%" src="https://blog.pythonwood.com/uploads/2013/本人微信公众号pythonwoodpub.jpg" title="1" width="40%">
<img alt="开发项目澳洲红酒微信服务号.jpg" height="50%" src="https://blog.pythonwood.com/uploads/2013/开发项目澳洲红酒微信服务号.jpg" title="1" width="40%"></p>