├── .DS_Store
├── .gitignore
├── .idea
├── Python-WeChat-ItChat.iml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── 01 itchat获取微信好友或者微信群分享文章
├── PythonItChat.py
└── README.md
├── 02 itchat获取微信公众号文章
└── PythonItChat.py
├── 03 itchat监听微信公众号发送的文章
└── PythonItChat.py
├── 04 itchat监听微信群或好友撤回的消息
└── PythonItChat.py
├── 05 itchat获得微信好友信息以及表图对比
└── PythonItChat.py
├── 06 python打印出微信被删除好友
└── PythonWeChat.py
├── 07 itchat自动回复好友
└── PythonWeChat.py
├── 08 itchat微信好友个性签名词云图
└── PythonWeChat.py
├── 09 itchat微信好友性别比例
└── PythonWeChat.py
├── 10 itchat微信群或者好友撤回消息
└── PythonWeChat.py
├── 11 itchat微信群或好友之间转发消息
└── PythonWeChat.py
├── README.md
└── 全栈Style.jpeg
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lb2281075105/Python-WeChat-ItChat/0bd603de86a888b1de226078d1c05a14bf7f08c9/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 | local_settings.py
56 |
57 | # Flask stuff:
58 | instance/
59 | .webassets-cache
60 |
61 | # Scrapy stuff:
62 | .scrapy
63 |
64 | # Sphinx documentation
65 | docs/_build/
66 |
67 | # PyBuilder
68 | target/
69 |
70 | # Jupyter Notebook
71 | .ipynb_checkpoints
72 |
73 | # pyenv
74 | .python-version
75 |
76 | # celery beat schedule file
77 | celerybeat-schedule
78 |
79 | # SageMath parsed files
80 | *.sage.py
81 |
82 | # dotenv
83 | .env
84 |
85 | # virtualenv
86 | .venv
87 | venv/
88 | ENV/
89 |
90 | # Spyder project settings
91 | .spyderproject
92 | .spyproject
93 |
94 | # Rope project settings
95 | .ropeproject
96 |
97 | # mkdocs documentation
98 | /site
99 |
100 | # mypy
101 | .mypy_cache/
102 |
--------------------------------------------------------------------------------
/.idea/Python-WeChat-ItChat.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
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 | 1523849860653
98 |
99 |
100 | 1523849860653
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 |
--------------------------------------------------------------------------------
/01 itchat获取微信好友或者微信群分享文章/PythonItChat.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | '''
3 | itchat:获取分享给群或者个人的技术文章
4 | (0) 熟悉itchat,(https://www.cnblogs.com/Chenjiabing/p/6907397.html)
5 | (1) itchat 扫码次数太多会被限制扫码登录微信。
6 | (2) itchat:获取分享给群或者个人的技术文章,提取出文章链接、文章标题、文章首页图片、文章内容
7 | (3) 通过获取到的文章链接,爬虫文章内容。
8 | (4) 判断是接收方(ToUserName)是谁、发送方(FromUserName)是谁就是通过唯一的ID来判别的。
9 | (5) python itchat 热登陆(itchat.auto_login(hotReload=True))
10 | (6) xpath模块爬取文章标题、文章内图片
11 | (7) 搭建web服务器环境(Mac使用XAMPP)
12 | (8) pymysql模块自动创建数据库、创建字段、保存内容到字段
13 | (9) navicat 的使用
14 | (10) python 相关模块的使用
15 | '''
16 |
17 | # 爬取微信群或者是好友分享的文章
18 | # 监听微信公众号分享的文章
19 | import re
20 | import itchat
21 | # import全部消息类型
22 | from itchat.content import *
23 | import urllib
24 | import lxml.etree
25 | import os
26 | import pymysql
27 | import uuid
28 | import json
29 | import requests
30 | import io
31 | # import cStringIO
32 | from pyquery import PyQuery as pq
33 | # mongodb
34 | from pymongo import MongoClient
35 | from bson.objectid import ObjectId
36 | from gridfs import *
37 | # import sys
38 | import reload
39 | # reload(sys)
40 | # sys.setdefaultencoding('utf8')
41 | # 连接数据库mysql
42 | table_cms_news = 'cms_news'
43 | table_cms_news_pic = 'cms_news_pic'
44 | # db = pymysql.connect(host='127.0.0.1', user='root', passwd='', db='itchat', charset='utf8')
45 | db = pymysql.connect(host='xxx', user='xxx', passwd='xxx', db='fz_afmcms', charset='utf8')
46 | cur = db.cursor()
47 |
48 | urlHost = 'xxx'
49 | # 连接到MongoDB
50 | client = MongoClient('xxx', xxx)
51 | db = client.images
52 | fs = GridFS(db, 'fs')
53 |
54 | # 处理个人分享消息
55 | # 包括文本、位置、名片、通知、分享(49重点)
56 | @itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING])
57 | def text_reply(msg):
58 | print(msg)
59 | # 微信里,每个用户和群聊,都使用很长的ID来区分
60 | if msg["MsgType"] == 49:
61 | print("个人分享文章地址链接Url:" + "---------------------------")
62 |
63 | xmlcontent = lxml.etree.HTML(get_html(msg["Url"]))
64 | title = xmlcontent.xpath('//h2[@class="rich_media_title"]/text()')
65 | imgArray = xmlcontent.xpath('//img/@data-src')
66 |
67 | # 来源
68 | source = xmlcontent.xpath('//span[@class="rich_media_meta rich_media_meta_text rich_media_meta_nickname"]/text()')
69 | time = xmlcontent.xpath('//em[@class="rich_media_meta rich_media_meta_text"]/text()')
70 | content = xmlcontent.xpath('//div[@class="rich_media_content "]')[0]
71 | print (msg["Content"])
72 | print("来源")
73 | print (source, time)
74 | # 下载图片
75 | print("下载图片")
76 | # print imgArray
77 | # print title[0]
78 | get_image(title, imgArray, source, time,msg["Url"],content)
79 |
80 | print ("个人分享文章类型编号MsgType:" + "---------------------------")
81 | print (msg["MsgType"])
82 | print ("个人分享Content:" + "---------------------------")
83 | print (msg["Content"])
84 | print ("个人分享FromUserName:" + "---------------------------")
85 | print (msg["FromUserName"])
86 | print ("个人分享ToUserName:" + "---------------------------")
87 | print (msg["ToUserName"])
88 | print ("个人分享链接标题FileName:" + "---------------------------")
89 | print (msg["FileName"])
90 |
91 | # return msg['Text']
92 | # itchat.send('%s: %s : %s' % (msg['Type'], msg['Text'],msg['Url']), msg['FromUserName'])
93 | print ("------------个人")
94 | # 获取到的信息是某某人和登录者之间的通讯,如果不是和登录这通讯就获取不到
95 | print (itchat.search_friends(userName=msg['FromUserName'])['NickName'])
96 | print (itchat.search_friends(userName=msg['ToUserName'])['NickName'])
97 |
98 | else:
99 | print ("不是个人分享的文章")
100 |
101 |
102 | # 处理群聊消息
103 | @itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING], isGroupChat=True)
104 | def text_reply(msg):
105 | print (msg)
106 | if msg["MsgType"] == 49:
107 | print ("群聊分享文章地址链接Url:" + "---------------------------")
108 | print (msg["Url"])
109 |
110 | xmlcontent = lxml.etree.HTML(get_html(msg["Url"]))
111 | title = xmlcontent.xpath('//h2[@class="rich_media_title"]/text()')
112 | imgArray = xmlcontent.xpath('//img/@src')
113 |
114 | # 来源
115 | source = xmlcontent.xpath('//span[@class="rich_media_meta rich_media_meta_text rich_media_meta_nickname"]/text()')
116 | time = xmlcontent.xpath('//em[@class="rich_media_meta rich_media_meta_text"]/text()')
117 | # content = xmlcontent.xpath('//div[@class="rich_media_content "]/p/span/text()')
118 | content = xmlcontent.xpath('//div[@class="rich_media_content "]')[0]
119 |
120 | # print msg["Content"]
121 | print ("内容")
122 |
123 | print ("来源")
124 | print (source,time)
125 | # 下载图片
126 | print ("下载图片")
127 | print (imgArray)
128 | print (msg["Url"])
129 | # print title[0]
130 | get_image(title,imgArray,source,time,msg["Url"],content)
131 |
132 | print ("-------------群--------")
133 | # itchat.send('%s: %s : %s' % (msg['Type'], msg['Text'], msg['Url']), msg['FromUserName'])
134 |
135 | print (msg['FromUserName'])
136 | print (msg['ToUserName'])
137 | # 这个是需要每次扫码登录都改变的receiver
138 | # receiver = "@bc33fe9613d2e671dd61c6c75e28fb4af8e1ee86fada62b5a893eafd71e2a797"
139 | # if msg['FromUserName'] == receiver:
140 | # print "----------- 自己在群里发的文章 ------------"
141 | # # 自己在群里发的文章
142 | # print "昵称:"
143 | # print itchat.search_friends(userName=msg['FromUserName'])['NickName']
144 | # print " ----------- "
145 | # print "群名称:"
146 | # print itchat.search_chatrooms(userName=msg['ToUserName'])['NickName']
147 | # chatRoomName = "呵呵各地"
148 | # # if itchat.search_chatrooms(userName=msg['ToUserName'])['NickName'] == chatRoomName:
149 | # # pass
150 | # # else:
151 | # # pass
152 | #
153 | # else:
154 | # # 群友发的文章
155 | # print "----------- 群友发的文章 -----------"
156 | # print "昵称:"
157 | # print msg['ActualNickName']
158 | # print " ----------- "
159 | # print "群名称:"
160 | # print itchat.search_chatrooms(userName=msg['FromUserName'])['NickName']
161 | # chatRoomName = "呵呵各地"
162 | # # if itchat.search_chatrooms(userName=msg['FromUserName'])['NickName'] == chatRoomName:
163 | # # pass
164 | # # else:
165 | # # pass
166 | else:
167 | print ("不是群聊分享的文章")
168 | # return msg['Text']
169 |
170 |
171 | # 处理微信公众号消息
172 | @itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING], isMpChat=True)
173 | def text_reply(msg):
174 | print (msg)
175 | print (itchat.search_mps(name='PythonCoder')[0]["NickName"])
176 | if msg["MsgType"] == 49:
177 | print ("监听到制定微信公众号分享的文章链接:")
178 | print (msg["Url"])
179 | else:
180 | print ("微信公众号分享的不是文章")
181 |
182 | # 获取网页内容
183 | def get_html(url):
184 | response = urllib.request.urlopen(url)
185 | html = response.read()
186 | return html.replace('data-src', 'src')
187 |
188 | # 下载图片
189 | def get_image(title,imgArray,source,time,linkurl,content):
190 | print ("标题")
191 | result = cur.execute("select source_url from cms_news WHERE source_url='"+ linkurl + "'")
192 | print(str(result) + '------------url-----------')
193 |
194 | titleJ = ''
195 | sourceJ = ''
196 | timeJ = ''
197 |
198 | if len(title) == 0:
199 | pass
200 | # titleJ = ''
201 | else:
202 | titleJ = title[0].strip().replace("\n", "")
203 | if len(source) == 0:
204 | # sourceJ = ''
205 | pass
206 | else:
207 | sourceJ = source[0].strip().replace("\n", "")
208 | if len(time) == 0:
209 | # timeJ = ''
210 | pass
211 | else:
212 | timeJ = time[0].strip().replace("\n", "")
213 |
214 | if len(imgArray) == 0:
215 | pass
216 | else:
217 | print ('wo de shi ')
218 | print (content)
219 | for item in imgArray:
220 |
221 | if len(item) == 0:
222 | imgArray.remove(item)
223 | continue
224 | if item.find('http') == 0:
225 | pass
226 | else:
227 | imgArray.remove(item)
228 |
229 | for item in imgArray:
230 |
231 | if item.find('http') == 0:
232 | print (item.find('http'))
233 | # 根据宽高来筛选图片
234 | data = requests.get(item).content
235 | tmpIm = io(data)
236 | from PIL import Image
237 | img = Image.open(tmpIm)
238 | width = img.size[0]
239 | height = img.size[1]
240 | if width < 460 and height < 460:
241 | imgArray.remove(item)
242 | else:
243 | pass
244 | else:
245 | continue
246 |
247 | print (imgArray)
248 |
249 | # print imgArray
250 | print ('图片筛选')
251 | # if len(imgArray) == 0:
252 | # return
253 | # return
254 | new_id = str(uuid.uuid1()).strip().replace("-", "")
255 | new_id1 = str(uuid.uuid1()).strip().replace("-", "")
256 | new_id2 = str(uuid.uuid1()).strip().replace("-", "")
257 |
258 | if result:
259 | print("------------数据库里面存在此数据------------")
260 | else:
261 | if os.path.isdir('./imgs'):
262 | pass
263 | else:
264 | os.mkdir("./imgs")
265 | if len(imgArray) == 0:
266 | pass
267 | else:
268 | for index,item in enumerate(imgArray):
269 | if index == 0:
270 | with open('imgs/' + new_id + ".png", 'a+') as file:
271 | file.write(get_html(item))
272 | file.close
273 | elif index == 1:
274 | with open('imgs/' + new_id1 + ".png", 'a+') as file:
275 | file.write(get_html(item))
276 | file.close
277 | elif index == 2:
278 | with open('imgs/' + new_id2 + ".png", 'a+') as file:
279 | file.write(get_html(item))
280 | file.close
281 | ima_dic = ""
282 | news_pic = ""
283 | news_pic_s = ""
284 | news_pic_t = ""
285 |
286 | news_content = ""
287 | news_content1 = ''
288 | # 内容
289 | if len(content) == 0:
290 | news_content = ""
291 | news_content1 = ''
292 | else:
293 | pass
294 | # news_content1 = content[0]
295 | # news_content = content
296 | content = lxml.etree.tostring(content, pretty_print=True, method='html')
297 | pqcontent = pq(unicode(content,'utf-8'))
298 |
299 | pqcontent('div').remove_attr('class')
300 | pqcontent('div').remove_attr(' ')
301 | pqcontent('div').remove_attr('style')
302 | pqcontent('div').remove_attr('id')
303 | pqcontent('url').remove_attr('class')
304 | pqcontent('url').remove_attr('cid')
305 | pqcontent('url').remove_attr('data-mark')
306 | pqcontent('url').remove_attr('style')
307 | pqcontent('url').remove_attr('mdtype')
308 | pqcontent('url').remove_attr('class')
309 | pqcontent('url').remove_attr('id')
310 | pqcontent('url').remove_attr('cid')
311 | pqcontent('code').remove_attr('style')
312 | pqcontent('a').remove_attr('href')
313 | pqcontent('a').remove_attr('class')
314 | pqcontent('a').remove_attr('style')
315 | pqcontent('a').remove_attr('id')
316 | pqcontent('a').remove_attr('data')
317 | pqcontent('p').remove_attr('style')
318 | pqcontent('p').remove_attr('class')
319 | pqcontent('p').remove_attr('id')
320 | pqcontent('p').remove_attr('data-mpa-powered-by')
321 | pqcontent('span').remove_attr('cid')
322 | pqcontent('span').remove_attr('mdtype')
323 | pqcontent('p').remove_attr('cid')
324 | pqcontent('p').remove_attr('mdtype')
325 | pqcontent('span').remove_attr('spellcheck')
326 | pqcontent('video').remove_attr('style')
327 | pqcontent('video').remove_attr('class')
328 | pqcontent('video').remove_attr('id')
329 | pqcontent('source').remove_attr('style')
330 | pqcontent('source').remove_attr('class')
331 | pqcontent('source').remove_attr('id')
332 | pqcontent('table').remove_attr('style')
333 | pqcontent('table').remove_attr('class')
334 | pqcontent('table').remove_attr('id')
335 | pqcontent('tr').remove_attr('style')
336 | pqcontent('tr').remove_attr('class')
337 | pqcontent('tr').remove_attr('id')
338 | pqcontent('img').remove_attr('style')
339 | pqcontent('img').remove_attr('class')
340 | pqcontent('img').remove_attr('id')
341 | pqcontent('img').remove_attr('data-s')
342 | pqcontent('img').remove_attr('data-copyright')
343 | pqcontent('img').remove_attr('data-ratio')
344 | pqcontent('td').remove_attr('style')
345 | pqcontent('td').remove_attr('class')
346 | pqcontent('td').remove_attr('id')
347 | pqcontent('h1').remove_attr('style')
348 | pqcontent('h1').remove_attr('class')
349 | pqcontent('h1').remove_attr('id')
350 | pqcontent('h2').remove_attr('style')
351 | pqcontent('h2').remove_attr('class')
352 | pqcontent('h2').remove_attr('id')
353 | pqcontent('h3').remove_attr('style')
354 | pqcontent('h3').remove_attr('class')
355 | pqcontent('h3').remove_attr('id')
356 | pqcontent('section').remove_attr('style')
357 | pqcontent('section').remove_attr('class')
358 | pqcontent('section').remove_attr('id')
359 | pqcontent('fieldset').remove_attr('style')
360 | pqcontent('fieldset').remove_attr('class')
361 | pqcontent('fieldset').remove_attr('id')
362 | pqcontent('span').remove_attr('style')
363 | pqcontent('span').remove_attr('class')
364 | pqcontent('span').remove_attr('id')
365 | pqcontent('span').remove_attr('md-inline')
366 | pqcontent('span').remove_attr('data-shimo-docs')
367 | pqcontent('strong').remove_attr('style')
368 | pqcontent('strong').remove_attr('class')
369 | pqcontent('strong').remove_attr('id')
370 | pqcontent('blockquote').remove_attr('style')
371 | pqcontent('blockquote').remove_attr('class')
372 | pqcontent('blockquote').remove_attr('id')
373 | pqcontent('legend').remove_attr('style')
374 | pqcontent('legend').remove_attr('class')
375 | pqcontent('legend').remove_attr('id')
376 | pqcontent('br').remove_attr('style')
377 | pqcontent('br').remove_attr('class')
378 | pqcontent('br').remove_attr('id')
379 | print ('-----------------------------------------')
380 | print (type(str(pqcontent.html())))
381 | print ('-----------------------------------------')
382 | # print pqcontent.html()
383 | if len(imgArray) == 0:
384 | pass
385 | else:
386 | ima_dic = imgArray[0]
387 |
388 | if len(imgArray) == 0:
389 | pass
390 | elif len(imgArray) == 1:
391 | news_pic = imgArray[0]
392 | data = requests.get(news_pic).content
393 | id = fs.put(data, filename = new_id + '.png')
394 | print (id)
395 | news_pic = urlHost + new_id + '.png'
396 | elif len(imgArray) == 2:
397 | news_pic = imgArray[0]
398 | news_pic_s = imgArray[1]
399 | for index,item in enumerate(imgArray):
400 | if index == 0:
401 | data = requests.get(item).content
402 | id = fs.put(data, filename=new_id + '.png')
403 | print (id)
404 | news_pic = urlHost + new_id + '.png'
405 | else:
406 | data = requests.get(item).content
407 | id = fs.put(data, filename=new_id1 + '.png')
408 | print (id)
409 | news_pic_s = urlHost + new_id1 + '.png'
410 | elif len(imgArray) >= 3:
411 | news_pic = imgArray[0]
412 | news_pic_s = imgArray[1]
413 | news_pic_t = imgArray[2]
414 | print (news_pic)
415 | print (news_pic_s)
416 | print (news_pic_t)
417 | for index,item in enumerate(imgArray):
418 | if index == 0:
419 | data = requests.get(item).content
420 | id = fs.put(data, filename=new_id + '.png')
421 | print (id)
422 | news_pic = urlHost + new_id + '.png'
423 | elif index == 1:
424 | data = requests.get(item).content
425 | id = fs.put(data, filename=new_id1 + '.png')
426 | print (id)
427 | news_pic_s = urlHost + new_id1 + '.png'
428 | else:
429 | data = requests.get(item).content
430 | id = fs.put(data, filename=new_id2 + '.png')
431 | print (id)
432 | news_pic_t = urlHost + new_id2 + '.png'
433 |
434 | cur.execute(
435 | 'INSERT INTO ' + table_cms_news_pic + ' (news_id,pic_url,pic_desc) VALUES (%s,%s,%s)',
436 | (new_id, news_pic,""))
437 | cur.execute(
438 | 'INSERT INTO ' + table_cms_news + ' (news_open_type,news_id,news_title,news_type,com_id,'\
439 | 'news_column_code1,news_column_name1,'\
440 | 'news_column_code2,news_column_name2,news_desc,news_pic,'\
441 | 'news_pic_s,news_pic_t,news_pic_is_show,'\
442 | 'news_content,news_source,news_cuser_name,'\
443 | 'news_ctime,news_url,news_status,view_count,platid,source_url) '\
444 | 'VALUES (%s,%s, %s,%s,%s, %s,%s,%s,%s, %s,%s, %s,%s,%s,'\
445 | ' %s,%s, %s,%s,%s,%s,%s,%s,%s)',
446 | ('1',new_id,titleJ,'1','','','','','','',news_pic,news_pic_s,
447 | news_pic_t,'1',pqcontent.html(),sourceJ,sourceJ,timeJ,"",
448 | '1',200,'weixin',linkurl))
449 |
450 | cur.connection.commit()
451 | print("------------------------ 插入成功 ----------------------------------")
452 |
453 | # 连接数据库
454 | def get_connect():
455 |
456 | try:
457 | # 创建表
458 | cur.execute(
459 | 'CREATE TABLE ' + table_cms_news + ' (id BIGINT(7) NOT NULL AUTO_INCREMENT, title VARCHAR(1000),url VARCHAR(10000), img VARCHAR(1000), source VARCHAR(1000), time VARCHAR(1000), created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(id))')
460 | except pymysql.err.InternalError as e:
461 | print(e)
462 | # 修改表字段
463 | cur.execute('ALTER DATABASE itchat CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci')
464 | cur.execute(
465 | 'ALTER TABLE ' + table_cms_news + ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
466 | cur.execute(
467 | 'ALTER TABLE ' + table_cms_news + ' CHANGE title title VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
468 | cur.execute(
469 | 'ALTER TABLE ' + table_cms_news + ' CHANGE url url VARCHAR(10000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
470 | cur.execute(
471 | 'ALTER TABLE ' + table_cms_news + ' CHANGE img img VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
472 | cur.execute(
473 | 'ALTER TABLE ' + table_cms_news + ' CHANGE source source VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
474 | cur.execute(
475 | 'ALTER TABLE ' + table_cms_news + ' CHANGE time time VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
476 |
477 | def loginCallback():
478 | pass
479 | def exitCallback():
480 | pass
481 | # 热登录(在一段时间内不用扫码登录还能保持登录状态)
482 | get_connect()
483 | print ("哈哈")
484 | itchat.auto_login(hotReload=True)
485 | # 绑定消息响应事件后,让itchat运行起来,监听消息
486 | itchat.run()
487 |
488 |
489 |
--------------------------------------------------------------------------------
/01 itchat获取微信好友或者微信群分享文章/README.md:
--------------------------------------------------------------------------------
1 | # Python-WeChat-ItChat
2 | itchat微信接口
3 |
--------------------------------------------------------------------------------
/02 itchat获取微信公众号文章/PythonItChat.py:
--------------------------------------------------------------------------------
1 | #coding=utf8
2 | import pickle
3 | import wechatsogou
4 | import urllib2
5 | import lxml.etree
6 | import os
7 | import pymysql
8 | import json
9 |
10 | # 添加一个文件,将已经发送成功的文章标题序列化到文件,防止多次运行导致重复发送邮件
11 | file_path = 'sent_articles_file'
12 |
13 | ws_api = wechatsogou.WechatSogouAPI()
14 |
15 | # 连接数据库
16 | tablename = 'pythonwechat'
17 | db = pymysql.connect(host='127.0.0.1', user='root', passwd='', db='itchat', charset='utf8')
18 | cur = db.cursor()
19 | cur.execute('USE itchat')
20 |
21 | # 获取公众号文章信息
22 | def get_article(gzh):
23 | articles = ws_api.get_gzh_article_by_history(gzh)
24 | print(len(articles['article']))
25 | return articles['article']
26 |
27 | # 获取网页内容
28 | def get_html(url):
29 | request = urllib2.Request(url)
30 | response = urllib2.urlopen(request)
31 | html = response.read()
32 | return html
33 |
34 | # 下载图片
35 | def get_image(title,imgArray,source,time):
36 | if os.path.isdir('./imgs'):
37 | pass
38 | else:
39 | os.mkdir("./imgs")
40 | for item in imgArray:
41 | with open('imgs/' + (item)[-30:].replace('/','-') + ".png", 'a+') as file:
42 | file.write(get_html(item))
43 | file.close
44 |
45 | cur.execute(
46 | 'INSERT INTO ' + tablename + ' (title, img,source,time) VALUES (%s, %s,%s, %s)',
47 | (title[0].strip().replace("\n", ""), json.dumps(imgArray, ensure_ascii=False),source[0].strip().replace("\n", ""),time[0].strip().replace("\n", "")))
48 | cur.connection.commit()
49 | print title[0]
50 | print("------------------------ 插入成功 ----------------------------------")
51 |
52 | # 连接数据库
53 | def get_connect():
54 |
55 | try:
56 | # 创建表
57 | cur.execute(
58 | 'CREATE TABLE ' + tablename + ' (id BIGINT(7) NOT NULL AUTO_INCREMENT, title VARCHAR(1000), img VARCHAR(1000), source VARCHAR(1000), time VARCHAR(1000), created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(id))')
59 | except pymysql.err.InternalError as e:
60 | print(e)
61 | # 修改表字段
62 | cur.execute('ALTER DATABASE itchat CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci')
63 | cur.execute(
64 | 'ALTER TABLE ' + tablename + ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
65 | cur.execute(
66 | 'ALTER TABLE ' + tablename + ' CHANGE title title VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
67 | cur.execute(
68 | 'ALTER TABLE ' + tablename + ' CHANGE img img VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
69 | cur.execute(
70 | 'ALTER TABLE ' + tablename + ' CHANGE source source VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
71 | cur.execute(
72 | 'ALTER TABLE ' + tablename + ' CHANGE time time VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')
73 |
74 |
75 | if '__main__' == __name__:
76 |
77 | get_connect()
78 |
79 | # 定义一个公众号列表
80 | gzh_list = ['技术最前线', 'python', '全民独立经纪人', '程序视界', '非著名程序员']
81 |
82 | for gzh in gzh_list:
83 | # 查找公众号之前,先从文件中反序列化出已经成功发送的文章列表
84 | if os.path.exists(file_path):
85 | f = open(file_path, 'rb')
86 | sent_list = pickle.load(f)
87 | f.close()
88 | articles = get_article(gzh)
89 | for article in articles:
90 | print(article['title'],'\n\t' ,article['content_url'])
91 |
92 | xmlcontent = lxml.etree.HTML(get_html(article['content_url']))
93 | title = xmlcontent.xpath('//h2[@class="rich_media_title"]/text()')
94 | imgArray = xmlcontent.xpath('//img[@data-type="png"]/@data-src')
95 | # 来源
96 | source = xmlcontent.xpath(
97 | '//span[@class="rich_media_meta rich_media_meta_text rich_media_meta_nickname"]/text()')
98 | time = xmlcontent.xpath('//em[@class="rich_media_meta rich_media_meta_text"]/text()')
99 | print "来源、时间"
100 | print source, time
101 | # 下载图片
102 | print "下载图片"
103 | get_image(title, imgArray, source, time)
104 |
105 |
--------------------------------------------------------------------------------
/03 itchat监听微信公众号发送的文章/PythonItChat.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | # itchat监听指定微信公众号发送的文章
3 |
4 | import itchat
5 | # import全部消息类型
6 | from itchat.content import *
7 |
8 | # 处理微信公众号消息
9 | @itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING], isMpChat=True)
10 | def text_reply(msg):
11 | # 监听指定微信公众号推送的文章信息
12 | print msg
13 | if itchat.search_mps(name='PythonCoder')[0]["NickName"] == "PythonCoder":
14 | # 爬取的是itchat.search_mps(name='PythonCoder')[0]["NickName"]的公众号文章
15 | if msg["MsgType"] == 49:
16 | print "监听到指定微信公众号分享的文章链接:"
17 | # 拿到链接以后就可以获取到文章信息
18 | print msg["Url"]
19 | else:
20 | print "微信公众号分享的不是文章"
21 | elif itchat.search_mps(name='非著名程序员')[0]["NickName"] == "非著名程序员":
22 | if msg["MsgType"] == 49:
23 | print "监听到指定微信公众号分享的文章链接:"
24 | # 拿到链接以后就可以获取到文章信息
25 | print msg["Url"]
26 | else:
27 | print "微信公众号分享的不是文章"
28 | elif itchat.search_mps(name='程序员大咖')[0]["NickName"] == "程序员大咖":
29 | if msg["MsgType"] == 49:
30 | print "监听到指定微信公众号分享的文章链接:"
31 | # 拿到链接以后就可以获取到文章信息
32 | print msg["Url"]
33 | else:
34 | print "微信公众号分享的不是文章"
35 | elif itchat.search_mps(name='iOS程序员大咖')[0]["NickName"] == "iOS程序员大咖":
36 | if msg["MsgType"] == 49:
37 | print "监听到指定微信公众号分享的文章链接:"
38 | # 拿到链接以后就可以获取到文章信息
39 | print msg["Url"]
40 | else:
41 | print "微信公众号分享的不是文章"
42 | else:
43 | pass
44 |
45 |
46 | itchat.auto_login(hotReload=True)
47 | # 绑定消息响应事件后,让itchat运行起来,监听消息
48 | itchat.run()
--------------------------------------------------------------------------------
/04 itchat监听微信群或好友撤回的消息/PythonItChat.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 |
3 | # 微信,找回好友、群聊用户撤回的消息
4 | # 说明:可以撤回的有文本文字、语音、视频、图片、位置、名片、分享、附件
5 |
6 | import itchat
7 | from itchat.content import *
8 | import sys
9 | import time
10 | import re
11 | import os
12 |
13 | reload(sys)
14 | sys.setdefaultencoding('utf8')
15 |
16 | msg_information = {}
17 | # 针对表情包的内容
18 | face_bug = None
19 |
20 | @itchat.msg_register([TEXT,PICTURE,FRIENDS,CARD,MAP,SHARING,RECORDING,ATTACHMENT,VIDEO],isFriendChat=True,isGroupChat=True)
21 | def receive_msg(msg):
22 | global face_bug
23 | # 接收消息的时间
24 | msg_time_rec = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
25 | if msg.has_key('ActualNickName'):
26 | # 群消息的发送者,用户的唯一标识
27 | from_user = msg['ActualUserName']
28 | # 发送者群内的昵称
29 | msg_from = msg['ActualNickName']
30 | # 获取所有好友
31 | friends = itchat.get_friends(update=True)
32 | for f in friends:
33 | # 如果群消息是好友发的
34 | if from_user == f['UserName']:
35 | # 优先使用好友的备注名称,没有则使用昵称
36 | if f['RemarkName']:
37 | msg_from = f['RemarkName']
38 | else:
39 | msg_from = f['NickName']
40 | break
41 | # 获取所有的群
42 | groups = itchat.get_chatrooms(update=True)
43 | for g in groups:
44 | # 根据群消息的FromUserName匹配是哪个群
45 | if msg['FromUserName'] == g['UserName']:
46 | group_name = g['NickName']
47 | group_menbers = g['MemberCount']
48 | break
49 | group_name = group_name + "(" + str(group_menbers) +")"
50 | else:
51 | # 优先使用备注名称
52 | if itchat.search_friends(userName=msg['FromUserName'])['RemarkName']:
53 | msg_from = itchat.search_friends(userName=msg['FromUserName'])['RemarkName']
54 | else:
55 | # 在好友列表中查询发送信息的好友昵称
56 | msg_from = itchat.search_friends(userName=msg['FromUserName'])['NickName']
57 | group_name = ""
58 | # 信息发送的时间
59 | msg_time = msg['CreateTime']
60 | # 每条信息的id
61 | msg_id = msg['MsgId']
62 | # 储存信息的内容
63 | msg_content = None
64 | # 储存分享的链接,比如分享的文章和音乐
65 | msg_share_url = None
66 | # 如果发送的消息是文本或者好友推荐
67 | if msg['Type'] == 'Text' or msg['Type'] == 'Friends':
68 | msg_content = msg['Text']
69 |
70 | # 如果发送的消息是附件、视频、图片、语音
71 | elif msg['Type'] == "Attachment" or msg['Type'] == "Video" \
72 | or msg['Type'] == 'Picture' \
73 | or msg['Type'] == 'Recording':
74 | # 内容就是他们的文件名
75 | msg_content = msg['FileName']
76 | # 下载文件
77 | msg['Text'](str(msg_content))
78 | # 如果消息为分享的位置信息
79 | elif msg['Type'] == 'Map':
80 | x, y, location = re.search(
81 | "" + x.__str__() + " 经度->" + y.__str__()
85 | else:
86 | msg_content = r"" + location
87 | # 如果消息为分享的音乐或者文章,详细的内容为文章的标题或者是分享的名字
88 | elif msg['Type'] == 'Sharing':
89 | msg_content = msg['Text']
90 | # 记录分享的url
91 | msg_share_url = msg['Url']
92 | face_bug = msg_content
93 | # 将信息存储在字典中,每一个msg_id对应一条信息
94 | msg_information.update(
95 | {
96 | msg_id: {
97 | "msg_from": msg_from,
98 | "msg_time": msg_time,
99 | "msg_time_rec": msg_time_rec,
100 | "msg_type": msg["Type"],
101 | "msg_content": msg_content,
102 | "msg_share_url": msg_share_url,
103 | "group_name":group_name
104 | }
105 | }
106 | )
107 |
108 | # 监听是否有消息撤回
109 | # 使用下面的装饰器监听,会发送4条消息
110 | # @itchat.msg_register(NOTE,isFriendChat=True,isGroupChat=True,isMpChat=True)
111 |
112 | # 监听是否有消息撤回
113 | # 使用下面的装饰器监听,会发送1条消息
114 | @itchat.msg_register(NOTE)
115 | def information(msg):
116 | # 这里如果这里的msg['Content']中包含消息撤回和id,就执行下面的语句
117 | if '撤回了一条消息' in msg['Content']:
118 | # 在返回的content查找撤回的消息的id
119 | old_msg_id = re.search("\(.*?)\<\/msgid\>", msg['Content']).group(1)
120 | # 获取到消息原文
121 | old_msg = msg_information.get(old_msg_id)
122 | # 如果发送的是表情包
123 | if len(old_msg_id)<11:
124 | # 发送撤回的提示给文件助手
125 | itchat.send_file(face_bug,toUserName='filehelper')
126 | # 把暂时存储的信息可以删除掉,也可以选择不删除
127 | # os.remove(face_bug)
128 | else:
129 | msg_body = old_msg.get('group_name') + old_msg.get('msg_from') +"\n" + old_msg.get('msg_time_rec') \
130 | + "撤回了:" + "\n" + r"" + old_msg.get('msg_content')
131 |
132 | # 如果是分享的文件被撤回了,那么就将分享的url加在msg_body中发送给文件助手
133 | if old_msg['msg_type'] == "Sharing":
134 | msg_body += "\n链接是:" + old_msg.get('msg_share_url')
135 | print msg_body
136 | # 将撤回消息发给文件助手
137 | itchat.send_msg(msg_body, toUserName='filehelper')
138 |
139 | # 有文件的话也要将文件发送回去
140 | if old_msg["msg_type"] == "Picture" \
141 | or old_msg["msg_type"] == "Recording" \
142 | or old_msg["msg_type"] == "Video" \
143 | or old_msg["msg_type"] == "Attachment":
144 | file = '@fil@%s' % (old_msg['msg_content'])
145 | itchat.send(msg=file, toUserName='filehelper')
146 | # 把暂时存储的信息可以删除掉,也可以选择不删除
147 | os.remove(old_msg['msg_content'])
148 | # 删除字典旧消息
149 | msg_information.pop(old_msg_id)
150 |
151 | itchat.auto_login(hotReload=True)
152 | itchat.run()
153 |
--------------------------------------------------------------------------------
/05 itchat获得微信好友信息以及表图对比/PythonItChat.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | import itchat
3 | import pandas as pd
4 | import matplotlib.pyplot as plt
5 |
6 | class pythonWeChat(object):
7 | def __init__(self):
8 | itchat.login ()
9 | self.friends = itchat.get_friends ( update=True )[0:]
10 | plt.rcParams['font.sans-serif'] = ['SimHei']
11 | plt.rcParams['axes.unicode_minus'] = False
12 |
13 | def save_info(self,NickName,Sex,Province,City,Signature):
14 | list=[]
15 | for i in self.friends:
16 | dict={}
17 | dict["NickName"]=i[NickName]
18 | if i[Sex]==1:
19 | dict["Sex"]="男"
20 | elif i[Sex]==2:
21 | dict["Sex"]="女"
22 | else:
23 | dict["Sex"]="不明性别"
24 | dict["Province"]=i[Province]
25 | dict["City"]=i[City]
26 | dict["Signature"]=i[Signature]
27 | list.append(dict)
28 | return list
29 | def save_csv(self):
30 | list=self.save_info("NickName","Sex","Province","City","Signature")
31 | # print(list)
32 | pf=pd.DataFrame(list)
33 | print(pf)
34 | try:
35 | pf.to_csv("wechat.csv",index=True,encoding="gb18030")
36 | except Exception as ret:
37 | print(ret)
38 | return pf
39 |
40 | def anysys(self,pf):
41 | res_sex = pd.DataFrame(pf["Sex"].value_counts())
42 | res_province = pd.DataFrame(pf["Province"].value_counts()[:15])
43 | index_list = []
44 | for i in list(res_province.index):
45 | if i=="":
46 | i="未知"
47 | index_list.append(i)
48 | res_province.index=index_list
49 | print(res_sex,res_province,type(res_province),type(res_sex))
50 | return res_sex,res_province
51 |
52 | def get_chart(self,train_data, feature_list, x_feature, chart_type, width_bar=None):
53 | """折线图、散点图、条形图绘制:
54 | parameters:
55 | train_data:DataFrame类型
56 | x_feature:特征,要统计的x轴的数据类别名称
57 | feature_list:特征列表
58 | chart_type:
59 | 0:折线图
60 | 1:散点图
61 | 2:条形图
62 | width_bar:num类型,条形图条的宽度,必须传值,否则多组数据统计时图形会覆盖
63 | """
64 | try:
65 | if x_feature and len(feature_list) > 0:
66 | for i in range(len(feature_list)):
67 | feature = feature_list[i]
68 | # 设置x轴刻度
69 | x_labels = list(train_data.index)
70 | x = range(len(x_labels))
71 | plt.xticks(x, x_labels)
72 | y = train_data[feature]
73 | if chart_type == 0:
74 | y = train_data[feature]
75 | plt.plot(x, y, label=x_feature)
76 | elif chart_type == 1:
77 | y = train_data[feature]
78 | plt.scatter(x, y, label=x_feature)
79 | elif chart_type == 2:
80 | x = [j + width_bar * i for j in x]
81 | plt.bar(x, y, width=width_bar, label=x_feature)
82 | plt.legend()
83 | plt.show()
84 | except Exception as e:
85 | print(e)
86 |
87 | if __name__ == '__main__':
88 | pythonWeChat = pythonWeChat()
89 | pwc = pythonWeChat.save_csv()
90 | res_sex, res_province = pythonWeChat.anysys(pwc)
91 | pythonWeChat.get_chart(res_sex, ["Sex"],"性别", 2, width_bar=0.2)
92 | pythonWeChat.get_chart(res_province, ["Province"], "省份", 2, width_bar=0.2)
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/06 python打印出微信被删除好友/PythonWeChat.py:
--------------------------------------------------------------------------------
1 | #coding:utf-8
2 | # 通过该程序可以发现被删除的好友
3 | import os
4 | import urllib, urllib2
5 | import re
6 | import cookielib
7 | import time
8 | import xml.dom.minidom
9 | import json
10 | import sys
11 | import math
12 |
13 | DEBUG = False
14 |
15 | MAX_GROUP_NUM = 35 # 每组人数
16 |
17 | QRImagePath = os.getcwd() + '/qrcode.jpg'
18 |
19 | tip = 0
20 | uuid = ''
21 |
22 | base_uri = ''
23 | redirect_uri = ''
24 |
25 | skey = ''
26 | wxsid = ''
27 | wxuin = ''
28 | pass_ticket = ''
29 | deviceId = 'e000000000000000'
30 |
31 | BaseRequest = {}
32 |
33 | ContactList = []
34 | My = []
35 |
36 | def getUUID():
37 | global uuid
38 |
39 | url = 'https://login.weixin.qq.com/jslogin'
40 | params = {
41 | 'appid': 'wx782c26e4c19acffb',
42 | 'fun': 'new',
43 | 'lang': 'zh_CN',
44 | '_': int(time.time()),
45 | }
46 |
47 | request = urllib2.Request(url=url, data=urllib.urlencode(params))
48 | response = urllib2.urlopen(request)
49 | data = response.read()
50 |
51 | regx = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)"'
52 | pm = re.search(regx, data)
53 |
54 | code = pm.group(1)
55 | uuid = pm.group(2)
56 |
57 | if code == '200':
58 | return True
59 |
60 | return False
61 |
62 |
63 | def showQRImage():
64 | global tip
65 |
66 | url = 'https://login.weixin.qq.com/qrcode/' + uuid
67 | params = {
68 | 't': 'webwx',
69 | '_': int(time.time()),
70 | }
71 |
72 | request = urllib2.Request(url=url, data=urllib.urlencode(params))
73 | response = urllib2.urlopen(request)
74 |
75 | tip = 1
76 |
77 | f = open(QRImagePath, 'wb')
78 | f.write(response.read())
79 | f.close()
80 |
81 | if sys.platform.find('darwin') >= 0:
82 | os.system('open %s' % QRImagePath)
83 | elif sys.platform.find('linux') >= 0:
84 | os.system('xdg-open %s' % QRImagePath)
85 | else:
86 | os.system('call %s' % QRImagePath)
87 |
88 | print '请使用微信扫描二维码以登录'
89 |
90 | def waitForLogin():
91 | global tip, base_uri, redirect_uri
92 |
93 | url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s' % (tip, uuid, int(time.time()))
94 |
95 | request = urllib2.Request(url=url)
96 | response = urllib2.urlopen(request)
97 | data = response.read()
98 |
99 | # window.code=500;
100 | regx = r'window.code=(\d+);'
101 | pm = re.search(regx, data)
102 |
103 | code = pm.group(1)
104 |
105 | if code == '201': # 已扫描
106 | print '成功扫描,请在手机上点击确认以登录'
107 | tip = 0
108 | elif code == '200': # 已登录
109 | print '正在登录...'
110 | regx = r'window.redirect_uri="(\S+?)";'
111 | pm = re.search(regx, data)
112 | redirect_uri = pm.group(1) + '&fun=new'
113 | base_uri = redirect_uri[:redirect_uri.rfind('/')]
114 | elif code == '408': # 超时
115 | pass
116 |
117 | return code
118 |
119 | def login():
120 | global skey, wxsid, wxuin, pass_ticket, BaseRequest
121 |
122 | request = urllib2.Request(url=redirect_uri)
123 | response = urllib2.urlopen(request)
124 | data = response.read()
125 | doc = xml.dom.minidom.parseString(data)
126 | root = doc.documentElement
127 |
128 | for node in root.childNodes:
129 | if node.nodeName == 'skey':
130 | skey = node.childNodes[0].data
131 | elif node.nodeName == 'wxsid':
132 | wxsid = node.childNodes[0].data
133 | elif node.nodeName == 'wxuin':
134 | wxuin = node.childNodes[0].data
135 | elif node.nodeName == 'pass_ticket':
136 | pass_ticket = node.childNodes[0].data
137 |
138 | if skey == '' or wxsid == '' or wxuin == '' or pass_ticket == '':
139 | return False
140 |
141 | BaseRequest = {
142 | 'Uin': int(wxuin),
143 | 'Sid': wxsid,
144 | 'Skey': skey,
145 | 'DeviceID': deviceId,
146 | }
147 |
148 | return True
149 |
150 |
151 | def webwxinit():
152 | url = base_uri + '/webwxinit?pass_ticket=%s&skey=%s&r=%s' % (pass_ticket, skey, int(time.time()))
153 | params = {
154 | 'BaseRequest': BaseRequest
155 | }
156 |
157 | request = urllib2.Request(url=url, data=json.dumps(params))
158 | request.add_header('ContentType', 'application/json; charset=UTF-8')
159 | response = urllib2.urlopen(request)
160 | data = response.read()
161 |
162 | if DEBUG == True:
163 | f = open(os.getcwd() + '/webwxinit.json', 'wb')
164 | f.write(data)
165 | f.close()
166 |
167 | global ContactList, My
168 | dic = json.loads(data)
169 | ContactList = dic['ContactList']
170 | My = dic['User']
171 |
172 | ErrMsg = dic['BaseResponse']['ErrMsg']
173 | if len(ErrMsg) > 0:
174 | print ErrMsg
175 |
176 | Ret = dic['BaseResponse']['Ret']
177 | if Ret != 0:
178 | return False
179 |
180 | return True
181 |
182 |
183 | def webwxgetcontact():
184 | url = base_uri + '/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s' % (pass_ticket, skey, int(time.time()))
185 |
186 | request = urllib2.Request(url=url)
187 | request.add_header('ContentType', 'application/json; charset=UTF-8')
188 | response = urllib2.urlopen(request)
189 | data = response.read()
190 |
191 | if DEBUG == True:
192 | f = open(os.getcwd() + '/webwxgetcontact.json', 'wb')
193 | f.write(data)
194 | f.close()
195 |
196 | dic = json.loads(data)
197 | MemberList = dic['MemberList']
198 |
199 | # 倒序遍历,不然删除的时候出问题..
200 | SpecialUsers = ['newsapp', 'fmessage', 'filehelper', 'weibo', 'qqmail', 'fmessage', 'tmessage', 'qmessage',
201 | 'qqsync', 'floatbottle', 'lbsapp', 'shakeapp', 'medianote', 'qqfriend', 'readerapp', 'blogapp',
202 | 'facebookapp', 'masssendapp', 'meishiapp', 'feedsapp', 'voip', 'blogappweixin', 'weixin',
203 | 'brandsessionholder', 'weixinreminder', 'wxid_novlwrv3lqwv11', 'gh_22b87fa7cb3c',
204 | 'officialaccounts', 'notification_messages', 'wxid_novlwrv3lqwv11', 'gh_22b87fa7cb3c', 'wxitil',
205 | 'userexperience_alarm', 'notification_messages']
206 | for i in xrange(len(MemberList) - 1, -1, -1):
207 | Member = MemberList[i]
208 | # 公众号/服务号
209 | if Member['VerifyFlag'] & 8 != 0:
210 | MemberList.remove(Member)
211 | # 特殊账号
212 | elif Member['UserName'] in SpecialUsers:
213 | MemberList.remove(Member)
214 | # 群聊
215 | elif Member['UserName'].find('@@') != -1:
216 | MemberList.remove(Member)
217 | # 自己
218 | elif Member['UserName'] == My['UserName']:
219 | MemberList.remove(Member)
220 |
221 | return MemberList
222 |
223 |
224 | def createChatroom(UserNames):
225 | MemberList = []
226 | for UserName in UserNames:
227 | MemberList.append({'UserName': UserName})
228 |
229 | url = base_uri + '/webwxcreatechatroom?pass_ticket=%s&r=%s' % (pass_ticket, int(time.time()))
230 | params = {
231 | 'BaseRequest': BaseRequest,
232 | 'MemberCount': len(MemberList),
233 | 'MemberList': MemberList,
234 | 'Topic': '',
235 | }
236 |
237 | request = urllib2.Request(url=url, data=json.dumps(params))
238 | request.add_header('ContentType', 'application/json; charset=UTF-8')
239 | response = urllib2.urlopen(request)
240 | data = response.read()
241 |
242 | dic = json.loads(data)
243 | ChatRoomName = dic['ChatRoomName']
244 | MemberList = dic['MemberList']
245 | DeletedList = []
246 | for Member in MemberList:
247 | # 被对方删除了
248 | if Member['MemberStatus'] == 4:
249 | DeletedList.append(Member['UserName'])
250 |
251 | ErrMsg = dic['BaseResponse']['ErrMsg']
252 | if len(ErrMsg) > 0:
253 | print ErrMsg
254 |
255 | return (ChatRoomName, DeletedList)
256 |
257 |
258 | def deleteMember(ChatRoomName, UserNames):
259 | url = base_uri + '/webwxupdatechatroom?fun=delmember&pass_ticket=%s' % (pass_ticket)
260 | params = {
261 | 'BaseRequest': BaseRequest,
262 | 'ChatRoomName': ChatRoomName,
263 | 'DelMemberList': ','.join(UserNames),
264 | }
265 |
266 | request = urllib2.Request(url=url, data=json.dumps(params))
267 | request.add_header('ContentType', 'application/json; charset=UTF-8')
268 | response = urllib2.urlopen(request)
269 | data = response.read()
270 | dic = json.loads(data)
271 | ErrMsg = dic['BaseResponse']['ErrMsg']
272 | if len(ErrMsg) > 0:
273 | print ErrMsg
274 |
275 | Ret = dic['BaseResponse']['Ret']
276 | if Ret != 0:
277 | return False
278 |
279 | return True
280 |
281 |
282 | def addMember(ChatRoomName, UserNames):
283 | url = base_uri + '/webwxupdatechatroom?fun=addmember&pass_ticket=%s' % (pass_ticket)
284 | params = {
285 | 'BaseRequest': BaseRequest,
286 | 'ChatRoomName': ChatRoomName,
287 | 'AddMemberList': ','.join(UserNames),
288 | }
289 |
290 | request = urllib2.Request(url=url, data=json.dumps(params))
291 | request.add_header('ContentType', 'application/json; charset=UTF-8')
292 | response = urllib2.urlopen(request)
293 | data = response.read()
294 | dic = json.loads(data)
295 | MemberList = dic['MemberList']
296 | DeletedList = []
297 | for Member in MemberList:
298 | # 被对方删除了
299 | if Member['MemberStatus'] == 4:
300 | DeletedList.append(Member['UserName'])
301 |
302 | ErrMsg = dic['BaseResponse']['ErrMsg']
303 | if len(ErrMsg) > 0:
304 | print ErrMsg
305 |
306 | return DeletedList
307 |
308 |
309 | def main():
310 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
311 | urllib2.install_opener(opener)
312 |
313 | if getUUID() == False:
314 | print '获取uuid失败'
315 | return
316 |
317 | showQRImage()
318 | time.sleep(1)
319 |
320 | while waitForLogin() != '200':
321 | pass
322 |
323 | os.remove(QRImagePath)
324 |
325 | if login() == False:
326 | print '登录失败'
327 | return
328 |
329 | if webwxinit() == False:
330 | print '初始化失败'
331 | return
332 |
333 | MemberList = webwxgetcontact()
334 |
335 | MemberCount = len(MemberList)
336 | print '通讯录共%s位好友' % MemberCount
337 |
338 | ChatRoomName = ''
339 | result = []
340 | for i in xrange(0, int(math.ceil(MemberCount / float(MAX_GROUP_NUM)))):
341 | UserNames = []
342 | NickNames = []
343 | DeletedList = ''
344 | for j in xrange(0, MAX_GROUP_NUM):
345 | if i * MAX_GROUP_NUM + j >= MemberCount:
346 | break
347 |
348 | Member = MemberList[i * MAX_GROUP_NUM + j]
349 | UserNames.append(Member['UserName'])
350 | NickNames.append(Member['NickName'].encode('utf-8'))
351 |
352 | print '第%s组...' % (i + 1)
353 | print ', '.join(NickNames)
354 | print '回车键继续...'
355 | raw_input()
356 |
357 | # 新建群组/添加成员
358 | if ChatRoomName == '':
359 | (ChatRoomName, DeletedList) = createChatroom(UserNames)
360 | else:
361 | DeletedList = addMember(ChatRoomName, UserNames)
362 |
363 | DeletedCount = len(DeletedList)
364 | if DeletedCount > 0:
365 | result += DeletedList
366 |
367 | print '找到%s个被删好友' % DeletedCount
368 | # 删除成员
369 | deleteMember(ChatRoomName, UserNames)
370 |
371 | resultNames = []
372 | for Member in MemberList:
373 | if Member['UserName'] in result:
374 | NickName = Member['NickName']
375 | if Member['RemarkName'] != '':
376 | NickName += '(%s)' % Member['RemarkName']
377 | resultNames.append(NickName.encode('utf-8'))
378 |
379 | print '---------- 被删除的好友列表 ----------'
380 | print '\n'.join(resultNames)
381 | print '-----------------------------------'
382 |
383 | # windows下编码问题修复
384 | class UnicodeStreamFilter:
385 | def __init__(self, target):
386 | self.target = target
387 | self.encoding = 'utf-8'
388 | self.errors = 'replace'
389 | self.encode_to = self.target.encoding
390 |
391 | def write(self, s):
392 | if type(s) == str:
393 | s = s.decode('utf-8')
394 | s = s.encode(self.encode_to, self.errors).decode(self.encode_to)
395 | self.target.write(s)
396 |
397 |
398 | if sys.stdout.encoding == 'cp936':
399 | sys.stdout = UnicodeStreamFilter(sys.stdout)
400 |
401 | if __name__ == '__main__':
402 | raw_input('请输入回车键继续本程序:')
403 | main()
404 | raw_input('请输入回车键结束本程序:')
405 |
--------------------------------------------------------------------------------
/07 itchat自动回复好友/PythonWeChat.py:
--------------------------------------------------------------------------------
1 | #coding=utf8
2 | import itchat
3 |
4 | # 自动回复
5 | # 封装好的装饰器,当接收到的消息是Text,即文字消息
6 | @itchat.msg_register('Text')
7 | def text_reply(msg):
8 | # 当消息不是由自己发出的时候
9 | if not msg['FromUserName'] == myUserName:
10 | # 发送一条提示给文件助手
11 | itchat.send_msg(u"[%s]收到好友@%s 的信息:%s\n" %
12 | (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(msg['CreateTime'])),
13 | msg['User']['NickName'],
14 | msg['Text']), 'filehelper')
15 | # 回复给好友
16 | return u'[自动回复]您好,我现在有事不在,一会再和您联系。\n已经收到您的的信息:%s\n' % (msg['Text'])
17 |
18 | if __name__ == '__main__':
19 | itchat.auto_login()
20 |
21 | # 获取自己的UserName
22 | myUserName = itchat.get_friends(update=True)[0]["UserName"]
23 | itchat.run()
24 |
--------------------------------------------------------------------------------
/08 itchat微信好友个性签名词云图/PythonWeChat.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | import itchat
3 | import re
4 | # jieba分词
5 | import jieba
6 | # wordcloud词云
7 | import matplotlib.pyplot as plt
8 | from wordcloud import WordCloud, ImageColorGenerator
9 | import os
10 | import numpy as np
11 | import PIL.Image as Image
12 |
13 | itchat.login()
14 | friends = itchat.get_friends(update=True)[0:]
15 | tList = []
16 | for i in friends:
17 | signature = i["Signature"].replace(" ", "").replace("span", "").replace("class", "").replace("emoji", "")
18 | rep = re.compile("1f\d.+")
19 | signature = rep.sub("", signature)
20 | tList.append(signature)
21 |
22 | # 拼接字符串
23 | text = "".join(tList)
24 |
25 | wordlist_jieba = jieba.cut(text, cut_all=True)
26 | wl_space_split = " ".join(wordlist_jieba)
27 |
28 | d = os.path.dirname(__file__)
29 | # 更改目录下Wordcloud生成图片,如:xiaohuangren.jpg
30 | alice_coloring = np.array(Image.open(os.path.join(d, "xiaohuangren.jpg")))
31 | # win系统需要更改font路径,如:C:\Windows\Fonts\msyhbd.ttc
32 | my_wordcloud = WordCloud(background_color="white", max_words=2000, mask=alice_coloring,
33 | max_font_size=40, random_state=42,
34 | font_path='/Users/sebastian/Library/Fonts/Arial Unicode.ttf')\
35 | .generate(wl_space_split)
36 |
37 | image_colors = ImageColorGenerator(alice_coloring)
38 | plt.imshow(my_wordcloud.recolor(color_func=image_colors))
39 | plt.imshow(my_wordcloud)
40 | plt.axis("off")
41 | plt.show()
42 |
43 | # 保存图片 并发送到手机
44 | my_wordcloud.to_file(os.path.join(d, "wechat_cloud.png"))
45 | itchat.send_image("wechat_cloud.png", 'filehelper')
46 |
--------------------------------------------------------------------------------
/09 itchat微信好友性别比例/PythonWeChat.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import itchat
3 | # 使用echarts
4 | from echarts import Echart, Legend, Pie
5 |
6 | # itchat先登录
7 | itchat.login()
8 | # 获取好友列表,列表里第一位是自己,所以从"自己"之后开始计算
9 | friends = itchat.get_friends(update=True)[0:]
10 |
11 | # male 男 1
12 | # female 女 2
13 | # other 其他
14 | male = female = other = 0
15 |
16 | for i in friends[1:]:
17 | sex = i["Sex"]
18 | if sex == 1:
19 | male += 1
20 | elif sex == 2:
21 | female += 1
22 | else:
23 | other += 1
24 |
25 | total = len(friends[1:])
26 |
27 | # 打印结果
28 | print u"男性好友:%.2f%%" % (float(male) / total * 100)
29 | print u"女性好友:%.2f%%" % (float(female) / total * 100)
30 | print u"未填性别:%.2f%%" % (float(other) / total * 100)
31 | chart = Echart(u'%s的微信好友性别比例' % (friends[0]['NickName']), 'from WeChat')
32 | chart.use(Pie('WeChat',
33 | [{'value': male, 'name': u'男性 %.2f%%' % (float(male) / total * 100)},
34 | {'value': female, 'name': u'女性 %.2f%%' % (float(female) / total * 100)},
35 | {'value': other, 'name': u'其他 %.2f%%' % (float(other) / total * 100)}],
36 | radius=["50%", "70%"]))
37 | chart.use(Legend(["male", "female", "other"]))
38 | del chart.json["xAxis"]
39 | del chart.json["yAxis"]
40 | chart.plot()
41 |
--------------------------------------------------------------------------------
/10 itchat微信群或者好友撤回消息/PythonWeChat.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os, re, shutil, time, collections, json
3 |
4 | from html.parser import HTMLParser
5 | from xml.etree import ElementTree as ETree
6 |
7 | import itchat
8 | from itchat.content import *
9 |
10 | msg_store = collections.OrderedDict()
11 | timeout = 600
12 | sending_type = {'Picture': 'img', 'Video': 'vid'}
13 | data_path = 'data'
14 | nickname = ''
15 | bot = None
16 |
17 | if __name__ == '__main__':
18 | if not os.path.exists(data_path):
19 | os.mkdir(data_path)
20 | # if the QR code doesn't show correctly, you can try to change the value
21 | # of enableCdmQR to 1 or -1 or -2. It nothing works, you can change it to
22 | # enableCmdQR=True and a picture will show up.
23 | bot = itchat.new_instance()
24 | bot.auto_login(hotReload=True, enableCmdQR=2)
25 | nickname = bot.loginInfo['User']['NickName']
26 |
27 | def clear_timeouted_message():
28 | now = time.time()
29 | count = 0
30 | for k, v in list(msg_store.items()):
31 | if now - v['ReceivedTime'] > timeout:
32 | count += 1
33 | else:
34 | break
35 | for i in range(count):
36 | item = msg_store.popitem(last=False)
37 |
38 | def get_sender_receiver(msg):
39 | sender = nickname
40 | receiver = nickname
41 | if msg['FromUserName'][0:2] == '@@': # group chat
42 | sender = msg['ActualNickName']
43 | m = bot.search_chatrooms(userName=msg['FromUserName'])
44 | if m is not None:
45 | receiver = m['NickName']
46 | elif msg['ToUserName'][0:2] == '@@': # group chat by myself
47 | if 'ActualNickName' in msg:
48 | sender = msg['ActualNickName']
49 | else:
50 | m = bot.search_friends(userName=msg['FromUserName'])
51 | if m is not None:
52 | sender = m['NickName']
53 | m = bot.search_chatrooms(userName=msg['ToUserName'])
54 | if m is not None:
55 | receiver = m['NickName']
56 | else: # personal chat
57 | m = bot.search_friends(userName=msg['FromUserName'])
58 | if m is not None:
59 | sender = m['NickName']
60 | m = bot.search_friends(userName=msg['ToUserName'])
61 | if m is not None:
62 | receiver = m['NickName']
63 | return HTMLParser().unescape(sender), HTMLParser().unescape(receiver)
64 |
65 | def print_msg(msg):
66 | msg_str = ' '.join(msg)
67 | print(msg_str)
68 | return msg_str
69 |
70 | def get_whole_msg(msg, download=False):
71 | sender, receiver = get_sender_receiver(msg)
72 | if len(msg['FileName']) > 0 and len(msg['Url']) == 0:
73 | if download: # download the file into data_path directory
74 | fn = os.path.join(data_path, msg['FileName'])
75 | msg['Text'](fn)
76 | if os.path.getsize(fn) == 0:
77 | return []
78 | c = '@%s@%s' % (sending_type.get(msg['Type'], 'fil'), fn)
79 | else:
80 | c = '@%s@%s' % (sending_type.get(msg['Type'], 'fil'), msg['FileName'])
81 | return ['[%s]->[%s]:' % (sender, receiver), c]
82 | c = msg['Text']
83 | if len(msg['Url']) > 0:
84 | try: # handle map label
85 | content_tree = ETree.fromstring(msg['OriContent'])
86 | if content_tree is not None:
87 | map_label = content_tree.find('location')
88 | if map_label is not None:
89 | c += ' ' + map_label.attrib['poiname']
90 | c += ' ' + map_label.attrib['label']
91 | except:
92 | pass
93 | url = HTMLParser().unescape(msg['Url'])
94 | c += ' ' + url
95 | return ['[%s]->[%s]: %s' % (sender, receiver, c)]
96 |
97 | @bot.msg_register([TEXT, PICTURE, MAP, CARD, SHARING, RECORDING,
98 | ATTACHMENT, VIDEO, FRIENDS], isFriendChat=True, isGroupChat=True)
99 | def normal_msg(msg):
100 | print_msg(get_whole_msg(msg))
101 | now = time.time()
102 | msg['ReceivedTime'] = now
103 | msg_id = msg['MsgId']
104 | msg_store[msg_id] = msg
105 | clear_timeouted_message()
106 |
107 | @bot.msg_register([NOTE], isFriendChat=True, isGroupChat=True)
108 | def note_msg(msg):
109 | print_msg(get_whole_msg(msg))
110 | content = HTMLParser().unescape(msg['Content'])
111 | try:
112 | content_tree = ETree.fromstring(content)
113 | except Exception:
114 | # invent/remove to chatroom
115 | return
116 | if content_tree is None:
117 | return
118 | revoked = content_tree.find('revokemsg')
119 | if revoked is None:
120 | return
121 | old_msg_id = revoked.find('msgid').text
122 | old_msg = msg_store.get(old_msg_id)
123 | if old_msg is None:
124 | return
125 | msg_send = get_whole_msg(old_msg, download=True)
126 | for m in msg_send:
127 | bot.send(m, toUserName='filehelper')
128 | clear_timeouted_message()
129 |
130 | if __name__ == '__main__':
131 | bot.run()
--------------------------------------------------------------------------------
/11 itchat微信群或好友之间转发消息/PythonWeChat.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | reload(sys)
4 | sys.setdefaultencoding('UTF8')
5 |
6 | import os, re, shutil, time, collections, json
7 | import requests
8 | from HTMLParser import HTMLParser
9 | from xml.etree import ElementTree as ETree
10 | import hashlib
11 |
12 | import itchat
13 | from itchat.content import *
14 |
15 | sending_type = {'Picture': 'img', 'Video': 'vid'}
16 | data_path = 'data'
17 | group_uin = {u'技术群1': '42235582@chatroom',
18 | u'技术群2': '2424504406@chatroom',
19 | u'技术群3': '6203978346@chatroom'}
20 | publishers = {u'技术群1': u'[阴险]',
21 | u'技术群2': u'[菜刀]',
22 | u'技术群3': u'[月亮]'}
23 | subscribers = [u'技术群1', u'技术群2', u'技术群3']
24 | nickname = ''
25 | bot = None
26 | as_chat_bot = True
27 |
28 | if __name__ == '__main__':
29 | if not os.path.exists(data_path):
30 | os.mkdir(data_path)
31 | # if the QR code doesn't show correctly, you can try to change the value
32 | # of enableCdmQR to 1 or -1 or -2. It nothing works, you can change it to
33 | # enableCmdQR=True and a picture will show up.
34 | bot = itchat.new_instance()
35 | bot.auto_login(hotReload=True, enableCmdQR=2)
36 | nickname = bot.loginInfo['User']['NickName']
37 |
38 | # tuling chat bot
39 | def talks_robot(info):
40 | api_url = 'http://www.tuling123.com/openapi/api'
41 | apikey = ''
42 | data = {'key': apikey, 'info': info.lower()}
43 | req = requests.post(api_url, data=data, timeout=10).text
44 | replys = json.loads(req)['text']
45 | return replys
46 |
47 | def get_sender_receiver(msg):
48 | sender = nickname
49 | receiver = nickname
50 | if msg['FromUserName'][0:2] == '@@': # group chat
51 | sender = msg['ActualNickName']
52 | m = bot.search_chatrooms(userName=msg['FromUserName'])
53 | if m is not None:
54 | receiver = m['NickName']
55 | elif msg['ToUserName'][0:2] == '@@': # group chat by myself
56 | if 'ActualNickName' in msg:
57 | sender = msg['ActualNickName']
58 | else:
59 | m = bot.search_friends(userName=msg['FromUserName'])
60 | if m is not None:
61 | sender = m['NickName']
62 | m = bot.search_chatrooms(userName=msg['ToUserName'])
63 | if m is not None:
64 | receiver = m['NickName']
65 | else: # personal chat
66 | m = bot.search_friends(userName=msg['FromUserName'])
67 | if m is not None:
68 | sender = m['NickName']
69 | m = bot.search_friends(userName=msg['ToUserName'])
70 | if m is not None:
71 | receiver = m['NickName']
72 | return HTMLParser().unescape(sender), HTMLParser().unescape(receiver)
73 |
74 | def print_msg(msg):
75 | msg_str = ' '.join(msg)
76 | print msg_str
77 | return msg_str
78 |
79 | def get_whole_msg(msg, prefix, download=False):
80 | if len(msg['FileName']) > 0 and len(msg['Url']) == 0:
81 | if download: # download the file into data_path directory
82 | fn = os.path.join(data_path, msg['FileName'])
83 | msg['Text'](fn)
84 | if os.path.getsize(fn) == 0:
85 | return []
86 | c = '@%s@%s' % (sending_type.get(msg['Type'], 'fil'), fn)
87 | else:
88 | c = '@%s@%s' % (sending_type.get(msg['Type'], 'fil'), msg['FileName'])
89 | return ['%s:' % (prefix), c]
90 | c = msg['Text']
91 | if len(msg['Url']) > 0:
92 | if len(msg['OriContent']) > 0:
93 | try: # handle map label
94 | content_tree = ETree.fromstring(msg['OriContent'])
95 | if content_tree is not None:
96 | map_label = content_tree.find('location')
97 | if map_label is not None:
98 | c += ' ' + map_label.attrib['poiname']
99 | c += ' ' + map_label.attrib['label']
100 | except:
101 | pass
102 | url = HTMLParser().unescape(msg['Url'])
103 | c += ' ' + url
104 | return ['%s: %s' % (prefix, c)]
105 |
106 | @bot.msg_register([TEXT], isFriendChat=True, isGroupChat=False)
107 | def personal_msg(msg):
108 | global as_chat_bot
109 | text = msg['Text'].strip()
110 | if text == u'闭嘴':
111 | as_chat_bot = False
112 | if text == u'张嘴吃药':
113 | as_chat_bot = True
114 | return talks_robot(text)
115 |
116 | @bot.msg_register([FRIENDS])
117 | def accept_friend(msg):
118 | bot.add_friend(msg['RecommendInfo']['UserName'], 3)
119 |
120 | @bot.msg_register([TEXT, PICTURE, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO],
121 | isFriendChat=False, isGroupChat=True)
122 | def group_msg(msg):
123 | # chat bot functionality
124 | global as_chat_bot
125 | if 'IsAt' in msg and msg['IsAt'] == True and \
126 | msg['Type'] == 'Text' and \
127 | msg['ToUserName'][0:2] != '@@' and \
128 | msg['Text'].find(u'@' + nickname) >= 0:
129 | text = msg['Text'].replace(u'@' + nickname, '').strip()
130 | if text == u'shit':
131 | as_chat_bot = False
132 | return
133 | if as_chat_bot:
134 | info = talks_robot(text)
135 | if info.find('No Know') >= 0:
136 | return
137 | if info.find('No Can') >= 0:
138 | return
139 | if info.find('Sorry') >= 0:
140 | return
141 | return info
142 | return
143 | # forwarding functionality
144 | group = msg['FromUserName']
145 | if msg['ToUserName'][0:2] == '@@': # message sent by myself
146 | group = msg['ToUserName']
147 | sender, receiver = get_sender_receiver(msg)
148 | if sender == '':
149 | sender = nickname
150 | # check if the message is from the publisher groups
151 | if receiver not in publishers: # if not in the publishers, do nothing
152 | return
153 | # turn on the chat bot if this magic happens
154 | if msg['Type'] == 'Text' and \
155 | hashlib.sha256(msg['Text']).hexdigest()[-2:] == '23':
156 | as_chat_bot = True
157 | # process message and send it to all the subscribed groups
158 | prefix = '%s[%s]' % (publishers[receiver], sender)
159 | msg_send = get_whole_msg(msg, prefix=prefix, download=True)
160 | if len(msg_send) == 0:
161 | return
162 | print_msg(msg_send)
163 | for tosend in subscribers:
164 | room = bot.search_chatrooms(name=tosend)
165 | for r in room:
166 | if r['UserName'] == group: # don't send back to the source
167 | continue
168 | if r['NickName'] != tosend: # check group name exact match
169 | continue
170 | for m in msg_send: # iterate messages (for images, videos, and files)
171 | bot.send(m, toUserName=r['UserName'])
172 |
173 | if __name__ == '__main__':
174 | bot.run()
175 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python-WeChat-ItChat
2 |
3 |
4 | itchat微信接口
5 |
6 | 01 itchat获取微信好友或者微信群分享文章
7 | 02 itchat获取微信公众号文章
8 | 03 itchat监听微信公众号发送的文章
9 | 04 itchat监听微信群或好友撤回的消息
10 | 05 itchat获得微信好友信息以及表图对比
11 | 06 python打印出微信被删除好友
12 | 07 itchat自动回复好友
13 | 08 itchat微信好友个性签名词云图
14 | 09 itchat微信好友性别比例
15 | 10 微信群或微信好友撤回消息拦截
16 | 11 itchat微信群或好友之间转发消息
17 |
--------------------------------------------------------------------------------
/全栈Style.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lb2281075105/Python-WeChat-ItChat/0bd603de86a888b1de226078d1c05a14bf7f08c9/全栈Style.jpeg
--------------------------------------------------------------------------------