Linux迷+Python粉 - bottlehttps://blog.pythonwood.com/2017-11-27T22:12:00+08:00微信公众平台开发(免费云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">&para;</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&nbsp;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">&#39;jszhou&#39;</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">&quot;&quot;&quot;</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">&quot;&quot;&quot;</span> <span class="nd">@app.get</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">checkSignature</span><span class="p">():</span> <span class="sd">&quot;&quot;&quot;</span> <span class="sd"> 这里是用来做接口验证的,从微信Server请求的URL中拿到“signature”,“timestamp”,&quot;nonce&quot;和“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">&amp;echostr=5853059253416844429&amp;timestamp=1362713741&amp;nonce=1362771581</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">token</span> <span class="o">=</span> <span class="s2">&quot;&quot;</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">&#39;signature&#39;</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">&#39;timestamp&#39;</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">&#39;nonce&#39;</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">&#39;echostr&#39;</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">&quot;</span><span class="si">%s%s%s</span><span class="s2">&quot;</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">&quot;wws:indentify error&quot;</span> <span class="k">def</span> <span class="nf">parse_msg</span><span class="p">():</span> <span class="sd">&quot;&quot;&quot;</span> <span class="sd"> 这里是用来解析微信Server Post过来的XML数据的,取出各字段对应的值,以备后面的代码调用,也可用lxml等模块。</span> <span class="sd"> &quot;&quot;&quot;</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">&quot;&quot;&quot;</span> <span class="sd"> 这里使用豆瓣的电影search API,通过关键字查询电影信息,这里的关键点是,一是关键字取XML中的Content值,</span> <span class="sd"> 二是如果Content中存在汉字,就需要先转码,才能进行请求</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">movieurlbase</span> <span class="o">=</span> <span class="s2">&quot;http://api.douban.com/v2/movie/search&quot;</span> <span class="n">DOUBAN_APIKEY</span> <span class="o">=</span> <span class="s2">&quot;&quot;</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">&quot;Content&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">))</span> <span class="c1"># 如果Content中存在汉字,就需要先转码,才能进行请求</span> <span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">?q=</span><span class="si">%s</span><span class="s1">&amp;apikey=</span><span class="si">%s</span><span class="s1">&#39;</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 &quot;&lt;p&gt;{&#39;url&#39;: %s}&lt;/p&gt;&quot; % url</span> <span class="c1"># url = &#39;%s%s?apikey=%s&#39; % (movieurlbase, id[&quot;Content&quot;], 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 &quot;&lt;p&gt;{&#39;movie&#39;: %s}&lt;/p&gt;&quot; % movie</span> <span class="c1"># info = movie[&quot;subjects&quot;][0][&quot;title&quot;] + movie[&quot;subjects&quot;][0][&quot;alt&quot;]</span> <span class="c1"># info = movie[&#39;title&#39;] + &#39;: &#39; + &#39;&#39;.join(movie[&#39;summary&#39;])</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">&quot;&quot;&quot;</span> <span class="sd"> 这里使用豆瓣的电影subject API,通过在query_movie_info()中拿到的电影ID,来获取电影的summary。</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">movieurlbase</span> <span class="o">=</span> <span class="s2">&quot;http://api.douban.com/v2/movie/subject/&quot;</span> <span class="n">DOUBAN_APIKEY</span> <span class="o">=</span> <span class="s2">&quot;&quot;</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">&#39;</span><span class="si">%s%s</span><span class="s1">?apikey=</span><span class="si">%s</span><span class="s1">&#39;</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">&quot;subjects&quot;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">&quot;id&quot;</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">&#39;&#39;</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">&#39;summary&#39;</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">&quot;/&quot;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">response_msg</span><span class="p">():</span> <span class="sd">&quot;&quot;&quot;</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"> &quot;&quot;&quot;</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">&quot;&quot;&quot;&lt;xml&gt;</span> <span class="s2"> &lt;ToUserName&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/ToUserName&gt;</span> <span class="s2"> &lt;FromUserName&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/FromUserName&gt;</span> <span class="s2"> &lt;CreateTime&gt;</span><span class="si">%s</span><span class="s2">&lt;/CreateTime&gt;</span> <span class="s2"> &lt;MsgType&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/MsgType&gt;</span> <span class="s2"> &lt;Content&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/Content&gt;</span> <span class="s2"> &lt;FuncFlag&gt;0&lt;/FuncFlag&gt;</span> <span class="s2"> &lt;/xml&gt;&quot;&quot;&quot;</span> <span class="c1">#图文格式</span> <span class="n">pictextTpl</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;&lt;xml&gt;</span> <span class="s2"> &lt;ToUserName&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/ToUserName&gt;</span> <span class="s2"> &lt;FromUserName&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/FromUserName&gt;</span> <span class="s2"> &lt;CreateTime&gt;</span><span class="si">%s</span><span class="s2">&lt;/CreateTime&gt;</span> <span class="s2"> &lt;MsgType&gt;&lt;![CDATA[news]]&gt;&lt;/MsgType&gt;</span> <span class="s2"> &lt;ArticleCount&gt;1&lt;/ArticleCount&gt;</span> <span class="s2"> &lt;Articles&gt;</span> <span class="s2"> &lt;item&gt;</span> <span class="s2"> &lt;Title&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/Title&gt;</span> <span class="s2"> &lt;Description&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/Description&gt;</span> <span class="s2"> &lt;PicUrl&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/PicUrl&gt;</span> <span class="s2"> &lt;Url&gt;&lt;![CDATA[</span><span class="si">%s</span><span class="s2">]]&gt;&lt;/Url&gt;</span> <span class="s2"> &lt;/item&gt;</span> <span class="s2"> &lt;/Articles&gt;</span> <span class="s2"> &lt;FuncFlag&gt;1&lt;/FuncFlag&gt;</span> <span class="s2"> &lt;/xml&gt; &quot;&quot;&quot;</span> <span class="c1">#判断Content内容,如果等于&quot;Hello2BizUser&quot;,表明是一个新关注用户,如果不是,就返回电影标题,电影简介</span> <span class="c1">#和电影海报组成的图文信息</span> <span class="k">if</span> <span class="n">msg</span><span class="p">[</span><span class="s2">&quot;Content&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;Hello2BizUser&quot;</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">&#39;FromUserName&#39;</span><span class="p">],</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;ToUserName&#39;</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">&#39;MsgType&#39;</span><span class="p">],</span> <span class="sa">u</span><span class="s2">&quot;欢迎关注豆瓣电影,输入电影名称即可快速查询电影讯息哦!&quot;</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">&#39;FromUserName&#39;</span><span class="p">],</span> <span class="n">msg</span><span class="p">[</span><span class="s1">&#39;ToUserName&#39;</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">&quot;subjects&quot;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">&quot;title&quot;</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">&quot;subjects&quot;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">&quot;images&quot;</span><span class="p">][</span><span class="s2">&quot;large&quot;</span><span class="p">],</span> <span class="n">Content</span><span class="p">[</span><span class="s2">&quot;subjects&quot;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">&quot;alt&quot;</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">&quot;__main__&quot;</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">&#39;127.0.0.1&#39;</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会更好。&nbsp;后注:此注不对。</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">&para;</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,&nbsp;开发项目澳洲红酒微信服务号,</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>