当前位置: 首页 > 编程日记 > 正文

200行代码,一行行教你自制微信机器人

640?wx_fmt=jpeg

参加 2018 AI开发者大会,请点击 ↑


作者|上海小胖,四大咨询的TechLead,mongoDB Professional 获得者。「Python专栏」专注Python领域的各种技术:爬虫、DevOps、人工智能、Web开发等。还有「大航海计划」,各种内推活动。


1

当初决定自己写这么个机器人有几个原因:

1) 用一个windows客户端工具运营公众号,真的很局限。虽然工具的功能很强大,能自动添加好友,自动拉好友入群,关键字回复等等,但是有一个绕不开的点,它是一款客户端工具,一款exe软件。

2) 我是Mac,为了用这个工具,就要开着虚拟机去操作。

3) 为了能一直自动添加好友,邀请入群,自动回复等一系列操作,电脑就不能合上。

4) 在外面突然想到一个点,想操作群发了,GG,无能为力。

5) 其他……


640?wx_fmt=jpeg


2


基于以上的原因,就想着自己来一套算了。毕竟可以定制化的话,之后想要什么就很方便了,而且在服务器端挂个python服务要比开个windows 就为了挂一个exe要很多。


那么首先需要确定需求,wxRobot我是准备长期维护、迭代的,所以显然不可能像网上那些个脚本一样,一个文件打通关。

另外功能自定义,就需要有版本引入,先做什么,痛点是什么都需要明确。我说下自己的选择:


1) 痛点是不能自主化的管理公众号、微信号。

2) 最急迫解决的是之前exe工具用到的功能,毕竟这也是我用这个工具的原因。那么有哪些功能呢?


  1. 群发消息

  2. 自动添加好友

  3. 邀请好友入群

  4. 关键字回复


3


既然是个项目,那么该有的组件一个不能少,看一下我的目录结构,这也是我自己总结出的common structure,大家可以参考一下,如果有好的建议欢迎大佬不吝留言。



640?wx_fmt=jpeg


  • app:项目业务模块。如果有多个模块就添加子目录,例如:一个网站下的博客模块、投票模块等。

  • core:核心组件。例如:数据库组件、类-文件组件等。

  • doc:文档。存放所有的文档,一般我会有固定的几个:CHANGELOG.md、BUGLIST.md、TODOLIST.md。

  • etc:配置文件。可以细分基本配置、业务配置等。

  • static:静态文件。

  • test:单元测试。

  • tmp:不需要进入版本控制的东西。

  • utility:辅助组件。和core相辅。


4


我把业务分为两块,filehelper算一个,好友相关的算一个。


好友相关的好理解,诸如添加好友、自动回复、邀请入群等。filehelper是什么呢?说白了,我们除了简单的自动回复、添加外,一定还希望做的更多吧?比如交互式指令。那这个filehelper就承担了指令收发的角色。

所有的业务模块都基于一个BaseHandle,这样底层的一些单元我就可以统一管控了:

色。


class BaseHandle:
   def __init__(self):
       '''
       self._meta = {
           'obj':{ # 消息发送对象
               'ul': [], # unlimit group
               'l': [], # limit group
               'r': [] # restrict
           },
           'reply':{
               'text': '',
               'article': '',
           }
       }
       '''

       self._usage = ''
       self._meta = {}
       self.current_cmd = None

   @property
   def usage(self):
       return self._usage

   @property
   def meta(self):
       return self._meta


再来看看FileHandle这个类,这也是当前版本最丰富的模块。这里面有两端逻辑:1.自动更新群组信息。 2.注册群发相关命令。


自动更新群组信息的目的是因为itchat模块会将所有联系人以及群组信息存储在本地的一个pkl文件中(pickle缩写?),如果想提升群发消息前获取群组列表的速度,那么就应该把数据放在内存里(反正也没多少数据),以下我把主要逻辑都罗列出来了,具体的代码太长了,暂时就不放出来了:


class FileHelper(BaseHandle):
   _usage = '''
   '''


   def __init__(self):
       super().__init__()
       self._meta = {
           ...
       }
       self._th_update = threading.Thread(target=self._update_meta, args=(), daemon=True)
       self.auto_update_groups()

   def auto_update_groups(self):
       # 自动更新群组
       self._th_update.start()

   def _update_meta(self):
       '''
       初始化限时推送的群组
       '''


       def _filter_restrict_groups(group):
           # 筛选出不能群发的群组

       def _filter_limit_groups(group):
           # 筛选出有时间限制的群组

       def _filter_unlimit_group(groups, limit_groups):
           # 筛选出不受限制的群组

       while True:
           time.sleep(30)
           # 更新群组信息



注册群发相关命令的思路就是做一个命令注册器,因为群发消息、文章、图片等行为类似,针对不同的用户群组发送不同的消息体。


所以我就把注册器的成员分成了:类型(文字、图片),对象(时间限制群组、无限制群组),行为(群发、单发)。


被装饰器注册的函数就成为了某个具有单独意义的指令了。


class FileHelper(BaseHandle):
   ...

   def update_cmd(self, cmd):
       # 更新命令,用于动态注册函数

   def _register_mass(func):
       @functools.wraps(func)
       def decorator(self, msg, *args, **kwargs):
           _action, _reply, _obj = func.__name__.split('_')
           if self._meta['action'][_action]:
               _to_user = self._meta['obj'][_obj]
               for _group in _to_user:
                   instance.send_msg(msg, _group['UserName'])
                   time.sleep(random.randrange(020))
               self._meta['action'][_action] = False
               self._current_cmd = None
               instance.send_msg('群发消息发送完毕', self._meta['extra']['UserName'])

       return decorator

   @_register_mass
   def mass_text_ul(self, msg=None):
       pass

   @_register_mass
   def mass_text_l(self, msg):
       pass

   @_register_mass
   def mass_text_test(self, msg):
       pass

   @_register_mass
   def mass_article_ul(self, msg):
       pass

   @_register_mass
   def mass_article_l(self, msg):
       pass


对比着效果图来看看:


640?wx_fmt=jpeg


5


接下来就是添加好友部分了,目前只支持自动接受好友,根据打招呼自动设置备注,关键字回复。


class Friend(BaseHandle):
   _usage = '''
   '''


   def __init__(self):
       super().__init__()
       self._meta = {
           ...
       }

   def is_biz(self, msg):
        
# 判断是不是商务合作


看下效果图:


640?wx_fmt=jpeg

6

讲完核心代码后,再来讲下中间经历的几个看不到的版本吧。


最一开始就是实现功能咯,没想很多,但是发现代码重复太多了,逻辑都差不多,一堆代码太丑了。优化后的代码就是第一版中的群发注册器函数。


接着原本的BaseHandle基类太重了,想的很好,把itchat方法都重写在基类里,这样就不用在其他地方调用itchat实例了,但是结果就是所有的子类都可以做同样的动作,就变成了filehelper.send_msg(), friend.send_image()了,这样对于同一个方法就会产生歧义了。因此就把基类里所有重写itchat方法的函数都去了,就保留了业务代码,并分别移到对应的类里去,而原本itchat的方法还是用itchat实例去操作。


接着关于itchat实例、FileHelper实例、Friend实例等的共享问题,容易造成重叠,重复使用、互相引用问题。解决办法目前就是把itchat实例单独在配置文件里初始化了,这也同时解决了上一个问题,其他业务类的实例采用单例模式,在类外面暴露一个统一的实例。


7


好了,这回是真花了功夫把这套代码讲完了,虽然还是相对简陋了,但迫于时间关系,先发出来了。之后会继续优化、健硕它。


今天也和一位大佬讨论了下这个项目,有很多值得思考的地方。


640?wx_fmt=jpeg


如果你对这份代码也感兴趣的话,欢迎底部留言~


--【完】--


2018 AI开发者大会


AI技术年度盛会即将开启!11月8-9日,来自Google、Amazon、微软、Facebook、LinkedIn、阿里巴巴、百度、腾讯、美团、京东、小米、字节跳动、滴滴、商汤、旷视、思必驰、第四范式、云知声等企业的技术大咖将带来工业界AI应用的最新思维。


如果你是某个AI技术领域的专业人才,或想寻求将AI技术整合至传统企业业务当中,扫码填写大会注册信息表,我们将从中挑选出20名相关性最高的幸运读者,送出单场分论坛入场券。大会嘉宾阵容和议题,请查看文末海报。


640?wx_fmt=png


此外,如果你想与所有参会大牛充分交流沟通,点击阅读原文购票,使用优惠码:AI2018-DBY 购买两日通票,立减999元;此外大会还推出了1024定制票,主会+分会自由组合,精彩随心。


640?wx_fmt=jpeg


推荐阅读

唇语识别技术的开源教程,听不见声音我也能知道你说什么!

首发|机器学习未来十年:你需要把握的趋势和热点

全面梳理百度世界大会,李彦宏又新吹了几个牛!

她说:真的,没事别嫁程序员

中心化交易所弊端尽显,DEX时代即将到来?用户分析告诉你

学习这么多算法到底在解决哪些问题?深度学习之外,我们要选择谁?


点击阅读原文,查看大会更多详情。2018 AI开发者大会——摆脱焦虑,拥抱技术前沿。

相关文章:

只有你想不到,没有它做不到——可随时变身的模块化机器人

默默单干不如灵活协作 独立单干虽自由灵活,但是和牛逼队友协作完成任务却是一件更美好、高效的事情。这不是只适用于人类社会的定律,在机器人世界里依然如此。 雷锋网消息,近日,著名英国杂志Nature Communications报道了一项关于协…

dlib 怎么安装vs2017_VS2017(Visual Studio2017) 搭建QT5开发环境

VS创建QT工程并添加到GitHub中大家好!欢迎打开并阅读本文,这次咱们说说怎么在VS中创建一个QT项目并且放到GitHub中吧因为GitHub或者码云Gitee都是一个很好的提供代码托管的地方对吧将自己的项目开源到上面,如果项目很好的话,肯定能收获到很多…

ASP.net 2.0中水晶报表迁移部署问题

asp.net 2.0的水晶报表,在迁移机器的时候,如果目标机器没有相应的程序集,在IIS中会报错。错误描述:Parser Error Description: An error occurred during the parsing of a resource required to service this request. Please re…

MySQL数据类型--------字符串类型实战

1. 背景 * MySQL支持的字符串类型有CHAR、VARCHAR、二进制、var二进制、BLOB、文本等等。 2. 字符串类型所需的存储和值范围 类型说明N的含义是否有字符集最大长度CHAR(N)定义字符字符是255VARCHAR(N)变长字符字符是16384BINARY(N)定长二进制字节字节否255VARBINARY(N)变长二进…

android怎么监听多点触摸_什么是多点触控技术,有哪些用途

自从乔布斯将触控技术用于苹果手机上,很多的手机厂商纷纷效仿,触控技术几乎成为手机的“标配”。其实,触控技术早就存在,只是一直未能大面积用于各种设备中,本文将带您认识神奇的触控技术。并非只有手机上可以看到触控…

帮AI摆脱“智障”之名,NLP这条路还有多远?

CSDN 出品的《2018-2019 中国人工智能产业路线图》V2.0 版即将重磅面世! V1.0 版发布以来,我们有幸得到了诸多读者朋友及行业专家的鼎力支持,在此表示由衷感谢。此次 V2.0 版路线图将进行新一轮大升级,内容包括 3 大 AI 前沿产业趋…

分页控件 WebPager [ZT]

两个类文件,点这里下载DLL文件>WebPager.dll1、 WebPager.csusing System;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.ComponentModel; [assembly:TagPrefix("WebPager", "wp")]namespace Xiaoqia…

typedef interrupt void (*PINT)(void)的分析

今天写程序时,在DSP2833x_PieVect.h看到typedef interrupt void (*PINT)(void)突然一愣,上网查了下发现在这是加了interrupt 中断关键字的函数指针,顺便记一下并复习一下函数指针。 本文参照下面的博客整理而来 http://blog.csdn.net/lg2lh/a…

webpack打开项目命令_配置webpack中dev.env.js、prod.env.js,解决不同命令下项目启动和打包到指定的环境...

前后端分离的项目开发中,我们有开发环境、测试环境、预生产环境和生产环境。1、开发环境下调试接口的时候,一般都会有好几个接口地址(开发服务器上的,本地的,接口开发人员的,七七八八的接口地址),要根据情况…

倒计时2天,如何搭乘通往AI全明星技术盛宴的末班车?(附大会完整版全日程)...

在操作系统、芯片领域跌倒的中国程序员,如何崛起?| 畅言GitHub服务中断24小时11分钟事故分析报告大咖指路:机器学习人才这些方向最紧缺!以太坊2.0? 亲历3天的Devcon我看到了这样一个以太坊 | 见闻录土味纪实文学 | 四十五度角仰望…

ASP.NET Web页面(.aspx)添加用户控件(.ascx)无显示的问题

写好的用户控件点击视图显示没有问题&#xff0c;但是将控件添加到Web窗体上时却显示如下图标:F5运行&#xff0c;查看源代码:有代码——但是页面却显示一片空白。分析代码&#xff0c;比较了一下能显示用户控件的其他web页面以及代码,发现只有如下代码不同:<script languag…

AI芯片的“战国时代”:计算力将会驶向何方?

CSDN 出品的《2018-2019 中国人工智能产业路线图》V2.0 版即将重磅面世&#xff01;V1.0 版发布以来&#xff0c;我们有幸得到了诸多读者朋友及行业专家的鼎力支持&#xff0c;在此表示由衷感谢。此次 V2.0 版路线图将进行新一轮大升级&#xff0c;内容包括 3 大 AI 前沿产业趋…

python 累积正态分布函数_为什么机器学习都围绕正态分布进行讨论?

作者 | Farhad Malik译者 | Monanfei责编 | 夕颜出品 | AI科技大本营(ID: rgznai100)为什么正态分布如此特殊&#xff1f;为什么大量数据科学和机器学习的文章都围绕正态分布进行讨论&#xff1f;我决定写一篇文章&#xff0c;用一种简单易懂的方式来介绍正态分布。在机器学习的…

Silverlight开发中遇到的几个小问题

1&#xff0c;程序发布时遇到错误&#xff1a; "Could not load type System.ServiceModel.Activation.HttpModule from assembly System.ServiceModel, Version3.0.0.0, Cultureneutral, PublicKeyTokenb77a5c561934e089" 可能引发此问题的原因&#xff1a; 安装.N…

最新DynamipsGUI2.8[模拟器]发布!(中文版-英文版下载)

DynamipsGUI2.8发布!2.0beta新增功能1.支持分布式Dynamips&#xff0c;最多支持9台PC联合进行路由交换模拟(可能存在问题,请测试提出问题)2.设备支持数量增加至路由器44台,交换机44台,适应超大型环境模拟3.支持2691,3725,3745(可能存在问题,请测试提出问题)4.集成最新dynamips-…

ue4 函数和宏区别_【UE4】通俗易懂 用蓝图来学习 C++ 基础知识

【前言】&#xff1a;用老罗来学UE蓝图&#xff1a;https://zhuanlan.zhihu.com/p/135297007​zhuanlan.zhihu.com再开个脑洞&#xff0c;用蓝图来类比学习C基础知识。C 刚开始学&#xff0c;所以本篇知识点不是特别全有些地方也可能不是特别准&#xff0c;望谅解&#xff0c;以…

c#自动登录网页,浏览页面

需求&#xff1a;客户的数据同时存在在另外一个不可控的系统中&#xff0c;需要和当前系统同步。 思路&#xff1a;自动登录另外一个系统&#xff0c;然后抓取数据&#xff0c;同步到本系统中。 技术点&#xff1a;模拟用户登录&#xff1b;保存登录状态&#xff1b;抓取数据 程…

用Servlet获取表单数据

1 //accept.jsp2 package servlets;3 4 import java.io.*;5 import javax.servlet.*;6 import javax.servlet.http.*;7 public class accept extends HttpServlet8 { 9 public String codeToString(String str) 10 {//处理中文字符串的函数 11 String sstr; 12 …

品质检测破局:工业视觉检测云平台为智能制造“点睛”

微波炉角落里的型号编码、空调背面不显眼的小螺钉、冰箱侧身的标签&#xff0c;它们的质量检测是生产线中最费人工的地方&#xff0c;也是制约智能制造的老大难。如果哪天这类瑕疵检测不再需要人工&#xff0c;这样的制造就真的称得上智能。最近&#xff0c;这一难题被美的和英…

算法导论Java实现-构建MaxHeap

package lhz.algorithm.chapter.six; /** * “构建堆”&#xff0c;《算法导论》6.3章节 Building a heap * 利用之前实现的<code>MaxHeapify</code>算法&#xff0c;构建max-heap。 * 伪代码&#xff1a; * BUILD-MAX-HEAP(A) * 1 heap-size[A] ← length[A]…

哲学家就餐问题c语言_哲学家就餐问题的一种Python解决方案

哲学家就餐问题一直是多线程同步问题的经典案例&#xff0c;本文中展示了多线程竞争共享资源带来的死锁问题&#xff0c;并介绍了一种简单的解决方案。哲学家就餐问题哲学家最擅长的就是思考和吃饭 &#xff0c;当他们感觉累的时候&#xff0c;就会拿起一双筷子去吃盘子里的寿司…

倒计时1天,2018 AI开发者报名通道即将关闭(附参会提醒)

参加 2018 AI开发者大会&#xff0c;请点击 ↑↑↑随着 AI 逐渐转为各大科技巨头的战略主战场&#xff0c;人工智能技术亦是长立风口&#xff0c;向阳而生。越来越多的发展趋势表明&#xff0c;未来的人工智能将逐步迈入广泛普及阶段&#xff0c;继而深入影响人类日常的生产生活…

Linux安全检查方法

检查系统密码文件,查看文件修改日期 [rootfedora ~]# ls -l /etc/passwd 查看passwd文件中有哪些特权用户 [rootfedora ~]# awk -F: $30 {print $1} /etc/passwd 查看系统里有没有空口令帐户 awk -F: length($2)0 {print $1} /etc/shadow 检查系…

Ubuntu Server 12.04下cobbler + dnsmasq +tftpd-hpa的安装配置(四)

四、自定义 kickstart 文件 Kickstart最早是RedHat公司用来自动部署RedHat操作系统的&#xff0c;通过Kickstart配置文件&#xff0c;通常安装过程中需要交互输入的信息就都可以自动应答。 通过Kickstart安装操作系统一般是这样几个步骤&#xff1a; Create a kickstart file. …

AI 技术实力图谱全解析!2018 中国 AI 开发者大会重磅来袭

【2018 AI 开发者大会图文直播】 11 月 8 日&#xff0c;由中国专业 IT 社区 CSDN 与硅谷 AI 社区 AICamp 联合出品的 2018 中国 AI 开发者大会&#xff08;AI NEXTCon&#xff09; 在北京拉开帷幕&#xff0c;近百位中美顶尖 AI 专家、知名企业代表、逾千名 AI 开发者&#x…

sql的不等于条件优化_SQL优化案例(2):OR条件优化

随后上一篇文章《 SQL优化案例(1)&#xff1a;隐式转换》的介绍&#xff0c;此处内容围绕OR的优化展开。在MySQL中&#xff0c;同样的查询条件&#xff0c;如果变换OR在SQL语句中的位置&#xff0c;那么查询的结果也会有差异&#xff0c;在多个复杂的情况下&#xff0c;可能会带…

所有 SAP 现在开设的标准课程

下面是 SAP 中国的教育培训首页&#xff0c;里面有 SAP 最新最完整的培训教育计划。 http://www30.sap.com/china/services/education/index.epx 从中可以看出&#xff0c;随着 SAP 的发展&#xff0c;BC4xx 系列课程已经发生了很大改变&#xff0c;取消了 BC404、BC406&#x…

动态展开所有_库存与市场需求之间如何“动态”共舞?库存计划动态模型构建分享...

库存(Stock)是用来提高交货速度、缓冲需求到单高峰的常用手段&#xff0c;通过按库存生产(MTS)的方法&#xff0c;用储备库存来满足客户需求、并按一定规则补货&#xff0c;无需等待生产周期&#xff0c;可极快地交付。相比按订单生产(MTO)的模式&#xff0c;采用安全库存可以有…

Linux下DNS简单部署(主从域名服务器)

一、DNS简介 DNS&#xff08;Domain Name System&#xff09;&#xff0c;域名系统&#xff0c;因特网上作为域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使用户更方便的访问互联网&#xff0c;而不用去记住能够被机器直接读取的IP数串。通过主机名&#xff0c;最终…

Neurala与CSDN宣布战略合作,将一站式AI平台BrainBuilder带给中国开发者

11 月 8 日&#xff0c;美国人工智能创新企业 Neurala 与中国开发者社区 CSDN 联合宣布&#xff0c;正式成为战略合作伙伴&#xff0c;通过双方的合作&#xff0c;将 BrainBuilder 平台提供给中国的更多开发者和教育培训机构。Brain Builder 是 Neurala 开发的一站式 AI 平台。…