Python微信公眾號開發—小白篇(1)


本文面向想通過Python學習公眾號開發的同學。一站式解決新手開發微信公眾號遇到的所有問題。

為了防止我的文章被到處轉載,貼一下我的公眾號【智能制造社區】,歡迎大家關注。

github倉庫地址https://github.com/injetlee/Python/tree/master/wechat

本篇文章首先實現與公眾號的對接,實現簡單的回復文字、圖片內容。下一篇會對接騰訊的AI平台,實現對照片的人臉檢測與分析,分析年齡、性別、表情、魅力值等。

准備工作

首先要注冊一個公眾號,這個很簡單,我們到微信公眾平台注冊就可以了,選擇個人訂閱號就可以。但是如果可以認證的,我建議選擇認證訂閱號,因為未認證的號很多功能權限都沒有。好了,話不多說進入正題。

1. 配置公眾號

  • 打開公眾號,在 開發->基本配置 頁面填寫內容。

配置.png

  • 下面說下需要填的內容,第一個URL要填的就是我們的服務地址,這個地址必須是外網地址並且是80端口。我們要本地開發時可以用 ngrok 解決。在ngrok.com官網下載。解壓后就是一個exe程序。在當前目錄下輸入.\ngrok.exe http 80即可啟動。啟動后如下圖所示,圖片中網址就是我們需要的

ngrok啟動.jpg

  • 然后我們復制紅色方框里面的地址到微信的URL輸入框中,比如我的就輸入http://c9b15df5.ngrok.io/connect 后面這個connect是我自己的服務的地址。就是我們在程序開發中自己命名的一個請求路徑,如果是新手的話建議按照我的來。不要改動,避免程序跑不起來。

  • 第二個Token,自己想一個就行了,隨便填,你可以當他為一個密碼。
  • 第三個自己生成就可以了。
  • 最后一個消息加解密方式選擇明文模式。配置到這里就結束了,我們先不要關閉這個頁面,等我們Python程序驗證部分寫好以后點擊頁面下面的提交就可以了。現在點會報錯的。

2.接口驗證部分代碼編寫

  • 查看官方文檔,當我們點擊配置頁面的提交按鈕時,微信后台會向我們配置的地址發送signature、timestamp、nonce、echostr四個信息,我們拿到這部分信息后通過哈希加密算法計算出(timestamp,nonce,token)的哈希值與微信發送的signature對比,如果相等則說明是微信后台的請求,然后把echostr返回,就表示驗證成功。

  • 這一步,我們使用三個庫,wechatpy-微信的Python SDK,falcon一個非常微小的Python Web框架,Waitress-一個Python WSGI服務器,當然在Linux上可以使用gunicorn代替waitress。通過pip install wechatpy[pycrypto]和pip install falcon,pip install waitress安裝。代碼如下,只需要把配置界面的token替換到代碼里

import falcon
from falcon import uri
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException

class Connect(object):

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_get</span><span class="hljs-params">(self, req, resp)</span>:</span>
    query_string = req.query_string
    query_list = query_string.split(<span class="hljs-string">'&amp;'</span>)
    b = {}
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> query_list:
        b[i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">0</span>]] = i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">1</span>]

    <span class="hljs-keyword">try</span>:
        check_signature(token=<span class="hljs-string">'這里填寫配置界面你輸入的token'</span>, signature=b[<span class="hljs-string">'signature'</span>], timestamp=b[<span class="hljs-string">'timestamp'</span>], nonce=b[<span class="hljs-string">'nonce'</span>])
        resp.body = (b[<span class="hljs-string">'echostr'</span>])
    <span class="hljs-keyword">except</span> InvalidSignatureException:
        <span class="hljs-keyword">pass</span>
    resp.status = falcon.HTTP_200

app = falcon.API()
connect = Connect()
app.add_route('/connect', connect)

  • 代碼寫好以后,我們在命令行輸入 waitress-serve --port=80 connect:app在80端口啟動我們的程序。啟動后如下圖,代表啟動成功,這時候我們到微信的配置頁面點擊提交,會彈出提交成功消息框,代表我們成功接入微信

waitress-serve.png

  • 簡單說明以下上面代碼,on_get函數接收微信發來的get請求,並且通過query_string拿到微信發送的參數,之后通過wechatpy的check_signature函數來校驗。校驗成功后把echostr返回給微信。

3. 發送文本信息給用戶

  • 接入成功后,就可以回復用戶的信息了。我們增加一個函數處理用戶發送的消息,整體代碼如下:
import falcon
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException
from wechatpy import parse_message
from wechatpy.replies import TextReply, ImageReply

class Connect(object):

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_get</span><span class="hljs-params">(self, req, resp)</span>:</span>
    query_string = req.query_string
    query_list = query_string.split(<span class="hljs-string">'&amp;'</span>)
    b = {}
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> query_list:
        b[i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">0</span>]] = i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">1</span>]

    <span class="hljs-keyword">try</span>:
        check_signature(token=<span class="hljs-string">'xxxxx'</span>, signature=b[<span class="hljs-string">'signature'</span>], timestamp=b[<span class="hljs-string">'timestamp'</span>], nonce=b[<span class="hljs-string">'nonce'</span>])
        resp.body = (b[<span class="hljs-string">'echostr'</span>])
    <span class="hljs-keyword">except</span> InvalidSignatureException:
        <span class="hljs-keyword">pass</span>
    resp.status = falcon.HTTP_200

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_post</span><span class="hljs-params">(self, req, resp)</span>:</span>
    xml = req.stream.read()
    msg = parse_message(xml)
    <span class="hljs-keyword">if</span> msg.type == <span class="hljs-string">'text'</span>:
        reply = TextReply(content=msg.content, message=msg)
        xml = reply.render()
        resp.body = (xml)
        resp.status = falcon.HTTP_200

app = falcon.API()
connect = Connect()
app.add_route('/connect', connect)

  • 我們導出了parse_message,TextReply,ImageReply函數。當拿到用戶消息時,判斷是文本消息,就原樣返回給用戶。現在我們啟動腳本后,向公眾號發送文本消息就會收到自動回復了。

4. 發送圖片信息給用戶

  • 我們簡單修改下on_post函數,使其不僅能處理文本,也能處理圖片信息。完整代碼如下:
import falcon
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException
from wechatpy import parse_message
from wechatpy.replies import TextReply, ImageReply

class Connect(object):

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_get</span><span class="hljs-params">(self, req, resp)</span>:</span>
    query_string = req.query_string
    query_list = query_string.split(<span class="hljs-string">'&amp;'</span>)
    b = {}
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> query_list:
        b[i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">0</span>]] = i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">1</span>]

    <span class="hljs-keyword">try</span>:
        check_signature(token=<span class="hljs-string">'xxxxxxx'</span>, signature=b[<span class="hljs-string">'signature'</span>], timestamp=b[<span class="hljs-string">'timestamp'</span>], nonce=b[<span class="hljs-string">'nonce'</span>])
        resp.body = (b[<span class="hljs-string">'echostr'</span>])
    <span class="hljs-keyword">except</span> InvalidSignatureException:
        <span class="hljs-keyword">pass</span>
    resp.status = falcon.HTTP_200

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_post</span><span class="hljs-params">(self, req, resp)</span>:</span>
    xml = req.stream.read()
    msg = parse_message(xml)
    <span class="hljs-keyword">if</span> msg.type == <span class="hljs-string">'text'</span>:
        reply = TextReply(content=msg.content, message=msg)
        xml = reply.render()
        resp.body = (xml)
        resp.status = falcon.HTTP_200
    <span class="hljs-keyword">elif</span> msg.type == <span class="hljs-string">'image'</span>:
        reply = ImageReply(media_id=msg.media_id, message=msg)
        xml = reply.render()
        resp.body = (xml)
        resp.status = falcon.HTTP_200

app = falcon.API()
connect = Connect()
app.add_route('/connect', connect)

  • 我們在代碼中加入了圖片處理邏輯,如果是圖片類型的消息,則把圖片返回給用戶。我們把圖片發送給微信后台后,會自動生成一個media_id,我們發送這個media_id就可以了。

效果圖

效果.png

總結

  • 以上就是第一部分的內容,我們首先做了接口認證,之后通過一個on_post函數處理了用戶發送的文本和圖片信息,不過目前就是原樣返回。

  • 下一篇我們接入騰訊AI平台,對照片進行人臉分析檢測之后再返回給用戶,不要走開哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM