• 技术文章 >头条

    用Python深度分析微信群聊,拥有高质量社群!

     Ly Ly2020-05-13 15:22:05转载2933
    1. 场景

    前几天,有一位小伙伴在后台给我留言,说自己有几十个微信群,自己精力有限,没法看过来,想要筛选一些高质量的群,让我是否能帮忙想想办法。

    其实,微信群里的所有聊天记录都在手机本地文件夹内,只需要导出来进行解密,然后来一波数据分析,就可以帮他筛选出高质量的社群。

    本篇文章将带大家用 Python 一步步来实现这个功能。

    2. 实现步骤

    第 1 步,导出微信聊天记录数据库

    首先,我们使用一部 Root 后的手机或者模拟器登录微信,找到微信聊天记录数据库,然后导出到本地。

    数据库文件的完整路径如下:

    1

    2

    # 微信聊天记录数据库完整路径

    /data/data/com.tencent.mm/MicroMsg/[当前登录微信的随机字符串]/EnMicroMsg.db

    需要注意的是,如果当前设备没有 Root,可以选择群聊消息进行一次迁移,然后从 Root 设备或模拟器中导出数据库。

    第 2 步,获取数据库的密码

    微信数据库的密码组成形式为:手机 IMEI + 微信 UIN,然后 md5 加密(32 位小写)的前 7 个数字。

    其中,手机的 IMEI 可以通过 *#06# 获取,如果是双卡手机,需要自己做一下判断。

    捕获.PNG

    微信的 UIN 在下面配置文件中,找到 name 属性为 default_uin 的 value 值,即为 UIN

    1

    2

    # 当前登录微信的配置文件

    /data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml

    最后,然后将 IMET 和 UIN 组成字符串,然后利用 MD5 进行加密,取 32 位小写的前 7 位即为微信数据库的密码。

    1.jpg

    第 3 步,破解数据库

    由于微信数据库是使用 SQLCipher 生成,所以要先安装 sqlcipher 命令行文件

    1

    2

    3

    # 安装sqlcipher命令行(Mac)

    brew install sqlcipher

    # Win可以去下载sqlcipher命令行文件

    然后,输入数据库的密码及解密方式等,导出破解后的数据库。

    lj.jpg

    第 4 步,分析数据库

    推荐使用 SQLiteSutdio 打开并分析上面破解后的数据库,重点查看 message、rcontact、chatroom 这 3 张表。

    微信所有的文字聊天记录都存放在 mesage 数据表中,包含:聊天内容、发送者、消息类型、创建时间等

    1589352732(1).png

    rcontact 为微信通讯录表,包含:微信 ID、昵称、备注名等

    chatroom 是群聊信息表,包含:群聊 ID、成员列表等

    第 5 步,Python 打开数据库并封装

    使用 sqlite3连接本地数据库文件,获取数据库对象和游标对象

    1

    2

    3

    4

    5

    6

    7

    import sqlite3

    def __init__(self, db_path="./weixin.db"):

        """

        本地数据库初始化

        """

        self.db = sqlite3.connect(db_path)

        self.cursor = self.db.cursor()

    接着,对数据库常用的操作,包含:增删改查,进行封装操作。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    def execute(self, sql, param=None):

        """

        sql: Sql语句,包含:增、删、改

        param:数据,可以为列表、字典,也可以为空

        """

        try:

            if param is None:

                self.cursor.execute(sql)

            else:

                if type(param) is list:

                    self.cursor.executemany(sql, param)

                else:

                    self.cursor.execute(sql, param)

                count = self.db.total_changes

                self.db.commit()

        except Exception as e:

            print(e)

            return False, e

        # 返回结果

        return True if count > 0 else False

    def query(self, sql, param=None):

        """

        查询语句

        sql:Sql语句

        param:参数,可以包含空

        retutn:成功返回True

        """

        if param is None:

            self.cursor.execute(sql)

        else:

            self.cursor.execute(sql, param)

        # 返回查询的结果

        return self.cursor.fetchall()

    第 6 步,通过群聊名称获取群聊 ID

    根据群聊昵称,使用 Sql 语句查询 rcontact 表,可以获取群聊的 ID 值

    1

    2

    3

    4

    5

    6

    7

    8

    9

    def __get_chartroom_id(self):

        """

        获取群聊的id

        :return:

        """

        res = self.db.query('select username from rcontact where nickname=?;', (self.chatroom_name,))

        # 群聊id

        chatroom_id = res[0][0]

        return chatroom_id

    第 7 步,获取群聊消息

    拥有群聊 ID 之后,紧接着查询 message 表,获取当前群聊的所有消息内容。

    1

    2

    3

    4

    5

    # message表:聊天记录表

    # isSend=0:对方发送的;isSend=1:自己发送的

    sql = "SELECT content FROM message WHERE talker='{}' and isSend=0".format(chatroom_id)

    # 查询表,获取所有的聊天记录

    result = self.db.query(sql)

    为了获取有效的消息内容,可以清洗掉自己发送的消息、系统消息、红包消息等内容

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    # 循环查询到的所有的消息

    for item in result:

        # 过滤数据

        if not item or not item[0] or item[0].find('xml') != -1 or item[0].find('sysmsg') != -1 or item[0].find(

                        '<msg>') != -1 or item[0].find('chatroom') != -1 or item[0].find('weixinhongbao') != -1:

             continue

        # 过滤掉自己发送的内容,不包含:

        temps = item[0].split(':')

        if len(temps) < 2:

            # print('自己发送的内容:' + item[0])

            continue

        # 每一条聊天记录,过滤掉发送者,只保留消息正文

        # 发送者

        send_from = item[0].split(':')[0]

        # 发送内容

        send_msg = "".join(item[0].split(':')[1:]).strip().replace("\"", "")

        # 过长的消息,也过滤掉

        if len(send_msg) > 200:

             continue

    对于群其他成员发送的内容,再过滤掉消息内容的前半部分,只保留消息正文

    l2.jpg

    第 8 步,生成词云

    使用 jieba 对群内有效的消息进行分词,然后使用 wordcloud 生成词云图。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    def generate_wordcloud(self, word):

        """

        生成词云

        :param word:

        :return:

        """

        img = WordCloud(font_path="./DroidSansFallbackFull.ttf", width=2000, height=2000,

                            margin=2, collocations=False).generate(word)

        plt.imshow(img)

        plt.axis("off")

        plt.show()

        # 保存图片

        img.to_file("{}.png".format("群聊"))

    # 分词

    temp = " ".join(jieba.cut(words, cut_all=True))

    # 生成词云

    generate_wordcloud(temp)

    第 9 步,新建排名表,插入数据

    为了统计群聊活跃度排名,我们需要新建一张表,包含:id、微信昵称、消息内容 3 个字段。

    1

    2

    3

    4

    5

    6

    7

    8

    def __create_top_table(self):

       """

       创建Top表

       :return:

       """

       # 创建Top表,如果存在就不重新创建

       result = self.db.execute(

                "CREATE TABLE IF NOT EXISTS top(uid integer primary key,name varchar(200),msg varchar(200))")

    接着,将上一步的每一条消息中的发送者 ID、发送内容 2 个字段插入到新建的 Top 表内

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    # 定义一个列表,加入所有要统计的数据

    msg_pre = []

    for item in result:

        # 发送者

        send_from = item[0].split(':')[0]

        # 发送内容

        send_msg = "".join(item[0].split(':')[1:]).strip().replace("\"", "")

        msg_pre.append((send_from, send_msg))

     # 把要统计的数据,插入到top表中

     self.db.execute("insert into top(uid,name,msg) values (NULL,?,?);", msg_pre)

    第 10 步,获取活跃度排名并可视化

    从 Top 数据表中,通过微信昵称查询出每一位成员发言的次数,并保存到一个列表中

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    def get_top_partner(self):

        """

        排名前15的成员

        :return:

        """

        sql = "SELECT name as 姓名,COUNT(*) as times FROM top GROUP BY name ORDER BY times DESC limit %d;" % self.top_num

        result = self.db.query(sql)

        for item in result:

            # 用户id

            id = item[0]

            # 发言次数

            count = item[1]

            # 获取用户的昵称,即:微信昵称

            username = self.get_username(id)

            self.top_data.append({

                'username': username,

                'count': count

                })

    最后,去除微信昵称的特殊符号,使用 pyecharts 将数据可视化。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    def draw_image(self):

        """

        数据可视化

        :return:

        """

        usernames = []

        counts = []

        for user in self.top_data:

             # 去除昵称中的特殊符号

             usernames.append(get_ava_string(user.get('username').strip())[0:8])

             counts.append(user.get('count'))

        def bar_chart() -> Bar:

                c = (

                    Bar()

                        .add_xaxis(usernames)

                        .add_yaxis("活跃度", counts)

                        .reversal_axis()

                        .set_series_opts(label_opts=opts.LabelOpts(position="right"))

                        .set_global_opts(title_opts=opts.TitleOpts(title="最活跃的%d个小伙伴" % self.top_num))

                )

                return c

        # 需要安装 snapshot-selenium 或者 snapshot-phantomjs

        make_snapshot(driver, bar_chart().render(), "bar.png")

    3. 最后

    上面的操作,通过生成的词云了解到当前群聊过去一段时间都在聊的话题及价值,通过对聊天记录的数据分析,获取到微信群聊活跃度排名。

    l3.png当然,也可以分析群成员潜水排名及某一位群成员的数据分析。

    专题推荐:python 微信
    上一篇:python基础知识整理(值得收藏) 下一篇:Python学习网教你自制屏幕翻译工具,代码量超少

    相关文章推荐

    • python可以开发微信么

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网