1. 程式人生 > 實用技巧 >案例一 微信聊天機器人

案例一 微信聊天機器人

閱讀目錄

一 簡介

wxpy基於itchat,使用了 Web 微信的通訊協議,,通過大量介面優化提升了模組的易用性,並進行豐富的功能擴充套件。實現了微信登入、收發訊息、搜尋好友、資料統計等功能。

總而言之,可用來實現各種微信個人號的自動化操作。

安裝:wxpy 支援 Python 3.4-3.6,以及 2.7 版本

pip3 install -U wxpy

二 登入微信

1、掃碼登入微信

from wxpy import *

bot = Bot()

2、cache_path=True

執行上面的程式,會彈出二維碼,用手機微信掃一掃即可實現登入。

但上面的程式有一個缺點,每次執行都要掃二維碼。不過wxpy非常貼心地提供了快取的選項,用於將登入資訊儲存下來,就不用每次都掃二維碼,如下

bot = Bot(cache_path=True) # 必須先登入過一次以後才可以使用快取

三 微信好友男女比例

from wxpy import *
from pyecharts import Pie

bot=Bot(cache_path=True) #注意手機確認登入

friends
=bot.friends()

attr=['男朋友','女朋友']
value
=[0,0]
for friend in

friends:
if friend.sex == 1: # 等於1代表男性
value[0]+=1
elif friend.sex == 2: #等於2代表女性
value[1]+=1

pie = Pie("Egon老師的好朋友們")
pie.add(
"", attr, value, is_label_show=True)
pie.render(
'sex.html')

四 微信好友地域分佈

from wxpy import *
from pyecharts import Map

bot=Bot(cache_path=True)

friends=bot.friends()

area_dic={}

for friend in friends:
if friend.province not in area_dic:
area_dic[friend.province]
=1
else:
area_dic[friend.province]
+=1

attr = area_dic.keys()
value
= area_dic.values()

map = Map("Egon老師好朋友們的地域分佈", width=1200, height=600)
map.add(
"好友地域分佈",
attr,
value,
maptype
='china',
is_visualmap
=True, #結合體VisualMap
visual_text_color='#000'
)
map.render(
'area.html')

五 微信好友資料分析之詞雲

bg.jpg

#安裝軟體
pip3 install jieba

pip3 install pandas

pip3 install numpy

pip3 install scipy

pip3 install wordcloud

from wxpy import *
import re
import jieba
import pandas as pd
import numpy

bot=Bot(cache_path=True)
friends
=bot.friends()

# 統計簽名
with open('signatures.txt','w',encoding='utf-8') as f:
for friend in friends:
# 對資料進行清洗,將標點符號等對詞頻統計造成影響的因素剔除
pattern=re.compile(r'[一-龥]+')
filterdata
=re.findall(pattern,friend.signature)
f.write(
''.join(filterdata))

#過濾停止詞
with open('signatures.txt','r',encoding='utf-8') as f:
data
=f.read()
segment
=jieba.lcut(data)

words_df</span>=pd.DataFrame({<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">segment</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:segment})
stopwords </span>= pd.read_csv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">stopwords.txt</span><span style="color: rgba(128, 0, 0, 1)">"</span>, index_col=False, quoting=3, sep=<span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(128, 0, 0, 1)">"</span>, names=[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">stopword</span><span style="color: rgba(128, 0, 0, 1)">'</span>], encoding=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
words_df </span>= words_df[~<span style="color: rgba(0, 0, 0, 1)">words_df.segment.isin(stopwords.stopword)]

#使用numpy進行詞頻統計
words_stat = words_df.groupby(by=['segment'])['segment'].agg({"計數":numpy.size})
words_stat
= words_stat.reset_index().sort_values(by=["計數"],ascending=False)
# print(words_stat)

#詞頻視覺化:詞雲,基於wordcloud庫,當然pyecharts也可以實現
from scipy.misc import imread
from wordcloud import WordCloud, ImageColorGenerator
import matplotlib.pyplot as plt

# 設定詞雲屬性

color_mask = imread('background.jfif')

color_mask = imread('bg.jpg')

color_mask = imread('bg1.jpeg')

wordcloud = WordCloud(
# font_path="simhei.ttf", # mac上沒有該字型
font_path="/System/Library/Assets/com_apple_MobileAsset_Font3/6d903871680879cf5606a3d2bcbef058e56b20d4.asset/AssetData/華文仿宋.ttf", # 設定字型可以顯示中文
background_color="white", # 背景顏色
max_words=100, # 詞雲顯示的最大詞數
mask=color_mask, # 設定背景圖片
max_font_size=100, # 字型最大值
random_state=42,
width
=1000, height=860, margin=2,# 設定圖片預設的大小,但是如果使用背景圖片的話, # 那麼儲存的圖片大小將會按照其大小儲存,margin為詞語邊緣距離
)

# 生成詞雲, 可以用generate輸入全部文字,也可以我們計算好詞頻後使用generate_from_frequencies函式
word_frequence = {x[0]:x[1]for x in words_stat.head(100).values}
print(word_frequence)
word_frequence_dict
= {}
for key in word_frequence:
word_frequence_dict[key]
= word_frequence[key]

print(word_frequence_dict)
wordcloud.generate_from_frequencies(word_frequence_dict)
# 從背景圖片生成顏色值
image_colors = ImageColorGenerator(color_mask)
# 重新上色
wordcloud.recolor(color_func=image_colors)
# 儲存圖片
wordcloud.to_file('output.png')
plt.imshow(wordcloud)
plt.axis(
"off")
plt.show()

詞雲
from wxpy import *
import re
import jieba
import pandas as pd
import numpy

bot=Bot(cache_path=True)
friends
=bot.friends()

# 統計簽名
with open('signatures.txt','w',encoding='utf-8') as f:
for friend in friends:
# 對資料進行清洗,將標點符號等對詞頻統計造成影響的因素剔除
pattern=re.compile(r'[一-龥]+')
filterdata
=re.findall(pattern,friend.signature)
f.write(
''.join(filterdata))

#過濾停止詞
with open('signatures.txt','r',encoding='utf-8') as f:
data
=f.read()
segment
=jieba.lcut(data)

words_df</span>=pd.DataFrame({<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">segment</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:segment})
stopwords </span>= pd.read_csv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">stopwords.txt</span><span style="color: rgba(128, 0, 0, 1)">"</span>, index_col=False, quoting=3, sep=<span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(128, 0, 0, 1)">"</span>, names=[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">stopword</span><span style="color: rgba(128, 0, 0, 1)">'</span>], encoding=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
words_df </span>= words_df[~<span style="color: rgba(0, 0, 0, 1)">words_df.segment.isin(stopwords.stopword)]

#使用numpy進行詞頻統計
words_stat = words_df.groupby(by=['segment'])['segment'].agg({"計數":numpy.size})
words_stat
= words_stat.reset_index().sort_values(by=["計數"],ascending=False)
print(words_stat)

#可是化詞雲
from pyecharts import WordCloud
word_frequence
= {x[0]:x[1]for x in words_stat.head(100).values}

name = word_frequence.keys()
value
= word_frequence.values()
wordcloud
= WordCloud(width=1300, height=620)
wordcloud.add(
"", name, value, word_size_range=[20, 100])
wordcloud.render(
'cy.html')

基於pyecharts繪製詞雲圖

停止詞,是由英文單詞:stopword翻譯過來的,原來在英語裡面會遇到很多a,the,or等使用頻率很多的字或詞,常為冠詞、介詞、副詞或連詞等。如果搜尋引擎要將這些詞都索引的話,那麼幾乎每個網站都會被索引,也就是說工作量巨大。可以毫不誇張的說句,只要是個英文網站都會用到a或者是the。那麼這些英文的詞跟我們中文有什麼關係呢? 在中文網站裡面其實也存在大量的stopword,我們稱它為停止詞。比如,我們前面這句話,“在”、“裡面”、“也”、“的”、“它”、“為”這些詞都是停止詞。這些詞因為使用頻率過高,幾乎每個網頁上都存在,所以搜尋引擎開發人員都將這一類詞語全部忽略掉。如果我們的網站上存在大量這樣的詞語,那麼相當於浪費了很多資源。原本可以新增一個關鍵詞,排名就可以上升一名的,為什麼不留著新增為關鍵詞呢?停止詞對SEO的意義不是越多越好,而是儘量的減少為宜。

中英文停止詞表:

able
about
above
according
accordingly
across
actually
after
afterwards
again
against
ain't
all
allow
allows
almost
alone
along
already
also
although
always
am
among
amongst
an
and
another
any
anybody
anyhow
anyone
anything
anyway
anyways
anywhere
apart
appear
appreciate
appropriate
are
aren
't
around
as
a
's
aside
ask
asking
associated
at
available
away
awfully
be
became
because
become
becomes
becoming
been
before
beforehand
behind
being
believe
below
beside
besides
best
better
between
beyond
both
brief
but
by
came
can
cannot
cant
can
't
cause
causes
certain
certainly
changes
clearly
c
'mon
co
com
come
comes
concerning
consequently
consider
considering
contain
containing
contains
corresponding
could
couldn
't
course
c
's
currently
definitely
described
despite
did
didn
't
different
do
does
doesn
't
doing
done
don
't
down
downwards
during
each
edu
eg
eight
either
else
elsewhere
enough
entirely
especially
et
etc
even
ever
every
everybody
everyone
everything
everywhere
ex
exactly
example
except
far
few
fifth
first
five
followed
following
follows
for
former
formerly
forth
four
from
further
furthermore
get
gets
getting
given
gives
go
goes
going
gone
got
gotten
greetings
had
hadn
't
happens
hardly
has
hasn
't
have
haven
't
having
he
hello
help
hence
her
here
hereafter
hereby
herein
here
's
hereupon
hers
herself
he
's
hi
him
himself
his
hither
hopefully
how
howbeit
however
i
'd
ie
if
ignored
i
'll
i'm
immediate
in
inasmuch
inc
indeed
indicate
indicated
indicates
inner
insofar
instead
into
inward
is
isn
't
it
it
'd
it'll
its
it
's
itself
i
've
just
keep
keeps
kept
know
known
knows
last
lately
later
latter
latterly
least
less
lest
let
let
's
like
liked
likely
little
look
looking
looks
ltd
mainly
many
may
maybe
me
mean
meanwhile
merely
might
more
moreover
most
mostly
much
must
my
myself
name
namely
nd
near
nearly
necessary
need
needs
neither
never
nevertheless
new
next
nine
no
nobody
non
none
noone
nor
normally
not
nothing
novel
now
nowhere
obviously
of
off
often
oh
ok
okay
old
on
once
one
ones
only
onto
or
other
others
otherwise
ought
our
ours
ourselves
out
outside
over
overall
own
particular
particularly
per
perhaps
placed
please
plus
possible
presumably
probably
provides
que
quite
qv
rather
rd
re
really
reasonably
regarding
regardless
regards
relatively
respectively
right
said
same
saw
say
saying
says
second
secondly
see
seeing
seem
seemed
seeming
seems
seen
self
selves
sensible
sent
serious
seriously
seven
several
shall
she
should
shouldn
't
since
six
so
some
somebody
somehow
someone
something
sometime
sometimes
somewhat
somewhere
soon
sorry
specified
specify
specifying
still
sub
such
sup
sure
take
taken
tell
tends
th
than
thank
thanks
thanx
that
thats
that
's
the
their
theirs
them
themselves
then
thence
there
thereafter
thereby
therefore
therein
theres
there
's
thereupon
these
they
they
'd
they'll
they're
they've
think
third
this
thorough
thoroughly
those
though
three
through
throughout
thru
thus
to
together
too
took
toward
towards
tried
tries
truly
try
trying
t
's
twice
two
un
under
unfortunately
unless
unlikely
until
unto
up
upon
us
use
used
useful
uses
using
usually
value
various
very
via
viz
vs
want
wants
was
wasn
't
way
we
we
'd
welcome
well
we
'll
went
were
we
're
weren't
we've
what
whatever
what
's
when
whence
whenever
where
whereafter
whereas
whereby
wherein
where
's
whereupon
wherever
whether
which
while
whither
who
whoever
whole
whom
who
's
whose
why
will
willing
wish
with
within
without
wonder
won
't
would
wouldn
't
yes
yet
you
you
'd
you'll
your
you
're
yours
yourself
yourselves
you
've
zero
zt
ZT
zz
ZZ

一下
一些
一切
一則
一天
一定
一方面
一旦
一時
一來
一樣
一次
一片
一直
一致
一般
一起
一邊
一面
萬一
上下
上升
上去
上來
上述
上面
下列
下去
下來
下面
不一
不久
不僅
不會
不但
不光
不單
不變
不只
不可
不同
不夠
不如
不得
不怕
不惟
不成
不拘
不敢
不斷
不是
不比
不然
不特
不獨
不管
不能
不要
不論
不足
不過
不問

與其
與否
與此同時
專門

兩者
嚴格
嚴重

個人
個別
中小
中間
豐富


為主
為了
為什麼
為什麼
為何
為著
主張
主要
舉行

乃至


之一
之前
之後
之後
之所以
之類
烏乎



也好
也是
也罷

瞭解
爭取

於是
於是乎
云云
互相
產生
人們
人家
什麼
什麼樣
什麼
今後
今天
今年
今後
仍然

從事
從而

他人
他們
他的
代替

以上
以下
以為
以便
以免
以前
以及
以後
以外
以後
以來
以至
以至於
以致


任何
任憑
任務
企圖
偉大
似乎
似的

但是

何況
何處
何時
作為

你們
你的
使得
使用
例如

依照
依靠
促進
保持

俺們

倘使
倘或
倘然
倘若
假使
假如
假若
做到

允許
充分
先後
先後
先生
全部
全面

共同
關於

其一
其中
其二
其他
其餘
其它
其實
其次
具體
具體地說
具體說來
具有
再者
再說


決定
況且
準備

幾乎
幾時

憑藉
出去
出來
出現
分別


別的
別說

前後
前者
前進
前面
加之
加以
加入
加強
十分

即令
即使
即便
即或
即若
卻不
原來


及其
及時
及至
雙方
反之
反應
反映
反過來
反過來說
取得
受到
變成

另一方面
另外
只是
只有
只要
只限

叫做
召開
叮咚

可以
可是
可能
可見

各個
各人
各位
各地
各種
各級
各自
合理

同一
同時
同樣
後來
後面

向著


否則

吧噠






嗚呼

周圍


呼哧





咱們



哈哈


哎呀
哎喲





哪個
哪些
哪兒
哪天
哪年
哪怕
哪樣
哪邊
哪裡

哼唷





啪達


喔唷
嗡嗡




嘎登





因為
因此
因而
固然

在下

堅決
堅持
基本
處理
複雜

多少
多數
多次
大力
大多數
大大
大家
大批
大約
大量
失去

她們
她的
好的
好象

如上所述
如下
如何
如其
如果
如此
如若
存在

寧可
寧願
寧肯

它們
它們的
它的
安全
完全
完成
實現
實際
宣佈
容易
密切

對於
對應

少數
爾後
尚且
尤其

就是
就是說

儘管
屬於
豈但
左右
巨大
鞏固

已經
幫助
常常

並不
並不是
並且
並沒有
廣大
廣泛
應當
應用
應該
開外
開始
開展
引起
強烈
強調


當前
當時
當然
當著
形成
徹底

彼此

往往

後來
後面

得出
得到
心裡
必然
必要
必須

怎麼
怎麼辦
怎麼樣
怎樣
怎麼
總之
總是
總的來看
總的來說
總的說來
總結
總而言之
恰恰相反

意思
願意
慢說
成為

我們
我的

或是
或者
戰鬥

所以
所有
所謂

擴大

抑或


按照
換句話說
換言之

掌握
接著
接著

故此
整個
方便
方面
旁人
無寧
無法
無論

既是
既然
時候
明顯
明確

是否
是的
顯然
顯著
普通
普遍
更加
曾經

最後
最大
最好
最後
最近
最高

有些
有關
有利
有力
有所
有效
有時
有點
有的
有著
有著


朝著

本著

來著
極了
構成
果然
果真

某個
某些
根據
根本
歡迎
正在
正如
正常

此外
此時
此間
毋寧

每個
每天
每年
每當

比如
比方
比較
毫不
沒有
沿
沿著
注意
深入
清楚
滿足
漫說

然則
然後
然後
然而

照著
特別是
特殊
特點
現代
現在
甚麼
甚而
甚至


由於
由此可見

的話
目前
直到
直接
相似
相信
相反
相同
相對
相對而言
相應
相當
相等
省得
看出
看到
看來
看看
看見
真是
真正

著呢

知道
確定

積極
移動
突出
突然
立即


等等

緊接著

縱令
縱使
縱然
練習
組成

經常
經過
結合
結果

絕對
繼續
繼而
維持
綜上所述
罷了
考慮


而且
而況
而外
而已
而是
而言
聯絡

能否
能夠


自個兒
自從
自各兒
自家
自己
自身

至於
良好

若是
若非
範圍
莫若
獲得

雖則
雖然
雖說
行為
行動
表明
表示


要不
要不是
要不然
要麼
要是
要求
規定
覺得
認為
認真
認識

許多

設使
設若

說明
諸位

誰知


起來
起見

趁著
越是

轉動
轉變
轉貼

較之

達到
迅速

過去
過來
運用
還是
還有

這個
這麼
這麼些
這麼樣
這麼點兒
這些
這會兒
這兒
這就是說
這時
這樣
這點
這種
這邊
這裡
這麼
進入
進步
進而
進行

連同
適應
適當
適用
逐步
逐漸
通常
通過
造成
遇到
遭到
避免

那個
那麼
那麼些
那麼樣
那些
那會兒
那兒
那時
那樣
那邊
那裡
那麼
部分
鄙人
採取
裡面
重大
重新
重要
鑑於
問題
防止

附近
限制

除了
除此之外
除非

隨著
隨著
集中
需要
非但
非常
非徒


順著
首先
高興
是不是
說說

補充:stopword

六 聊天機器人

1、為微信傳輸助手傳送訊息

這裡的file_helper就是微信的檔案傳輸助手,我們給檔案傳輸助手傳送一條訊息,可以在手機端的檔案傳輸助手中收到括號內的訊息

bot.file_helper.send('egon say hello')

2、收發訊息@bot.register()

from wxpy import *
bot=Bot(cache_path=True)

@bot.register()
def recv_send_msg(recv_msg):
print('收到的訊息:',recv_msg.text) # recv_msg.text取得文字
return 'EGON自動回覆:%s' %recv_msg.text

# 進入Python命令列,讓程式保持執行
embed()

3、自動給老婆回覆資訊

當你在網咖吃著雞,操作騷出天際時,你老婆打電話讓你回家吃飯,此時你怎麼辦。。。

from wxpy import *
bot=Bot(cache_path=True)

girl_friend=bot.search('Quincy.Coder')[0]
print(girl_friend)

@bot.register(chats=girl_friend) # 接收從指定好友發來的訊息,傳送者即recv_msg.sender為指定好友girl_friend
def recv_send_msg(recv_msg):
print('收到的訊息:',recv_msg.text) # recv_msg.text取得文字
if recv_msg.sender == girl_friend:
recv_msg.forward(bot.file_helper,prefix
='老婆留言: ') #在檔案傳輸助手裡留一份,方便自己忙完了回頭檢視
return '老婆最美麗,我對老婆的愛如滔滔江水,連綿不絕' #給老婆回一份

embed()

4、從微信群中定位好友

老闆的資訊一定要及時回覆

bot=Bot(cache_path=True)

company_group=bot.groups().search('群名稱')[0]

boss=company_group.search('老闆的微信名稱')[0]

@bot.register(chats=company_group) #接收從指定群發來的訊息,傳送者即recv_msg.sender為組
def recv_send_msg(recv_msg):
print('收到的訊息:',recv_msg.text)
if recv_msg.member == boss:
recv_msg.forward(bot.file_helper,prefix
='老闆發言: ')
return '老闆說的好有道理,深受啟發'

embed()

5、聊天機器人

給所有人自動回覆

import json
import requests
from wxpy import *
bot = Bot(console_qr=True, cache_path=True)

# 呼叫圖靈機器人API,傳送訊息並獲得機器人的回覆
def auto_reply(text):
url
= "http://www.tuling123.com/openapi/api"
api_key
= "申請圖靈機器人獲取key值放到這裡"
payload
= {
"key": api_key,
"info": text,
}
r
= requests.post(url, data=json.dumps(payload))
result
= json.loads(r.content)
return "[EGON微信測試,請忽略] " + result["text"]

@bot.register()
def forward_message(msg):
return auto_reply(msg.text)

embed()

給指定的群回覆

import json
import requests
from wxpy import *
bot = Bot(console_qr=True, cache_path=True)

group=bot.groups().search('教學部三人組')[0]
print(group)

# 呼叫圖靈機器人API,傳送訊息並獲得機器人的回覆
def auto_reply(text):
url
= "http://www.tuling123.com/openapi/api"
api_key = "申請圖靈機器人獲取key值放到這裡"
payload
= {
"key": api_key,
"info": text,
}
r
= requests.post(url, data=json.dumps(payload))
result
= json.loads(r.content)
return "[EGON微信測試,請忽略] " + result["text"]

@bot.register(group)
def forward_message(msg):
return auto_reply(msg.text)

embed()

給指定的人回覆

import json
import requests
from wxpy import *
bot = Bot(console_qr=True, cache_path=True)

girl_friend=bot.search('Quincy.Coder')[0]

# 呼叫圖靈機器人API,傳送訊息並獲得機器人的回覆
def auto_reply(text):
url
= "http://www.tuling123.com/openapi/api"
api_key = "申請圖靈機器人獲取key值放到這裡"
payload
= {
"key": api_key,
"info": text,
}
r
= requests.post(url, data=json.dumps(payload))
result
= json.loads(r.content)
return "[EGON微信測試,請忽略] " + result["text"]

@bot.register()
def forward_message(msg):
if msg.sender == girl_friend:
return auto_reply(msg.text)

embed()