Python新型冠状病毒疫情数据自动爬取+统计+发送报告+数据屏幕(三)发送篇

在这里插入图片描述

今天介绍的项目是使用 Itchat 发送统计报告

项目功能设计:
  1. 定时爬取疫情数据存入Mysql
  2. 进行数据分析制作疫情报告
  3. 使用itchat给亲人朋友发送分析报告(本文)
  4. 基于Django做数据屏幕
  5. 使用Tableau做数据分析

来看看最终效果
在这里插入图片描述
目前已经完成,预计2月12日前更新

使用 itchat 发送数据统计报告
  • itchat 是一个基于 web微信的一个框架,但微信官方并不允许使用这种类型模块,所以近几年注册的微信无法使用 itchat 想知道自己的微信能否使用 itchat 登陆 微信网页版 试一试能否登陆,如果可以登陆那么恭喜你可以使用 itchat 开发一些有趣的东西,如果不能使用,那么也没关系我们可以使用一些发送短信的接口,或者使用 python 发送邮件的模块也可以达到效果,下图是微信机器人自动发送的消息报告:
    在这里插入图片描述

  • 分析问题:我们的目的是使用 itchat 定时发送报告,而且要有交互聊天功能,前面提到过青云客机器人我们这次项目就使用它来回复聊天,要做到这两点,我们必须使用多任务,所以这次程序使用了 python 多线程多方式来实现这些功能,让主进程运行 itchat聊天机器人程序 创建一个线程来定时爬取数据,发送数据报告

  • 源码展示环节:
    这次的源码是结合了这过个系列前两篇文章的延伸,如果你也想要搭建一个这样的机器人,你需要先去看看我这个系列前面的两篇博客,创建数据库,搭建mysql,这次我就不仔细讲解源码了,itchat API 也比较简单,我就简单介绍一下,如果你想使用需要修改和注意到一些地方,先看看源码:

import re
import time
import json
import datetime
import threading
import requests
import pymysql
import itchat
import pandas as pd


@itchat.msg_register(itchat.content.TEXT)
def print_content(msg):
    start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(msg["CreateTime"]))
    friend_name = itchat.search_friends(userName=msg['FromUserName'])['NickName']
    print(start_time, friend_name)
    if friend_name in ["微信名1", "微信名2"]:  # 允许启动聊天程序的对象,就是你想让聊天机器人自动回复谁给你发的微信:把微信名放在列表里
        if friend_name == "自己的微信名":  # 自己的微信名
            if msg['Text'].split(":")[0] == "nlp":
                itchat.send(nlp_chat(msg['Text'].split(":")[1]), toUserName="filehelper")
        else:
            itchat.send("bAI: " + nlp_chat(msg['Text']), toUserName=msg["FromUserName"])


def nlp_chat(msg):
    url = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=%s" % msg
    response = requests.get(url)
    content = json.loads(response.content.decode())
    if content["result"]:
        return "哈哈😀"
    else:
        return content["content"]


class VirusSupervise(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.url = 'https://3g.dxy.cn/newh5/view/pneumonia?scene=2&clicktime=1579582238&enterid=1579582238&from=timeline&isappinstalled=0'
        self.rumor_url = "https://3g.dxy.cn/newh5/view/pneumonia_rumors?from=dxy"
        self.all_data = list()
        self.host_ip = "39.107.99.31"  # 39.107.99.31
        self.host_user = "cooh"  # cooh

    def run(self):
        while True:
            num = 9
            sleep_time = 3600 * num  # 一小时
            time.sleep(10)
            self.insert_wis_sql()  # 更新数据库
            self.send_msg()  # 发送消息

    def request_page(self):
        """
        请求页面数据
        """
        res = requests.get(self.url)
        res.encoding = 'utf - 8'
        pat0 = re.compile('window.getAreaStat = ([\s\S]*?)</script>')
        data_list = pat0.findall(res.text)
        data = data_list[0].replace('}catch(e){}', '')
        data = eval(data)
        return data

    def deep_spider(self, data, province_name):
        """
        深度提取出标签里详细的数据
        :param data:
        :param province_name:
        :return:
        """
        for temp_data in data:
            self.all_data.append([temp_data["cityName"], temp_data["confirmedCount"], temp_data["curedCount"],
                                  temp_data["deadCount"], province_name, datetime.date.today(),
                                  datetime.datetime.now().strftime('%H:%M:%S')])

    def filtration_data(self):
        """
        过滤数据
        """
        temp_data = self.request_page()
        province_short_names, confirmed_counts, cured_counts, dead_counts = list(), list(), list(), list()
        for i in temp_data:
            province_short_names.append(i['provinceShortName'])  # 省份
            confirmed_counts.append(i['confirmedCount'])  # 确诊
            cured_counts.append(i['curedCount'])  # 治愈
            dead_counts.append(i['deadCount'])  # 死亡
            self.deep_spider(i['cities'], i["provinceShortName"])  # 深度解析数据添加到实例属性中

        data_all = pd.DataFrame(self.all_data, columns=["城市", "确诊", "治愈", "死亡", "省份", "日期", "时间"])
        # print(data_all[data_all["省份"] == "陕西"])
        df = pd.DataFrame()
        df['省份'] = province_short_names
        df['确诊'] = confirmed_counts
        df['治愈'] = cured_counts
        df['死亡'] = dead_counts
        print(df)
        # data_all.to_csv("疫情数据_1.csv", encoding="utf_8_sig")
        return data_all

    @staticmethod
    def insert_sql(data):
        coon = pymysql.connect(host="127.0.0.1", user="root", password="963369", database="epidemic_data",
                                    charset="utf8")
        number = int(pd.read_sql("select cycle from data_all order by id DESC limit 1", coon)["cycle"].to_list()[0]) + 1
        print("正在插入数据mysql: ", number)
        cursor = coon.cursor()  # 创建事务
        sql = "insert into data_all(cityName, confirmedCount, curedCount, deadCount, province_name, " \
              "date_info, detail_time, cycle) values(%s, %s, %s, %s, %s, %s, %s, %s)"

        print("正在插入数据...")
        for cityName, confirmedCount, curedCount, deadCount, province_name, date_info, detail_time in zip(data["城市"],
                        data["确诊"], data["治愈"], data["死亡"], data["省份"], data["日期"], data["时间"]):
            cursor.execute(sql, (cityName, confirmedCount, curedCount, deadCount, province_name, date_info, detail_time, number))
            coon.commit()
        print("数据插入完成...")
        cursor.close()
        coon.close()

    def insert_wis_sql(self):
        data = self.filtration_data()
        self.insert_sql(data)
        coon = pymysql.connect(host=self.host_ip, user=self.host_user, password="963369", database="epidemic_data", charset="utf8")
        number = int(pd.read_sql("select cycle from all_data order by id DESC limit 1", coon)["cycle"].to_list()[0]) + 1
        print("正在向阿里云服务器插入数据: ", number)
        cursor = coon.cursor()  # 创建事务
        sql = "insert into all_data(cityName, confirmedCount, curedCount, deadCount, province_name, " \
              "date_info, detail_time, cycle) values(%s, %s, %s, %s, %s, %s, %s, %s)"

        print("正在插入数据...")
        for cityName, confirmedCount, curedCount, deadCount, province_name, date_info, detail_time in zip(data["城市"],
                        data["确诊"], data["治愈"], data["死亡"], data["省份"], data["日期"], data["时间"]):
            cursor.execute(sql, (cityName, confirmedCount, curedCount, deadCount, province_name, date_info, detail_time, number))
            coon.commit()
        print("数据插入完成...")
        cursor.close()
        coon.close()

    def send_msg(self):
        content = self.data_analysis()  # 提取数据分析报告
        name_list = ["爸爸", "妈妈", "姐姐"]  # 这个列表里放的是聊天机器人发送报告的对象,就是你打算给哪些人发送报告
        itchat.auto_login(hotReload=True)
        for name in name_list:
            temp_info = itchat.search_friends(name)[0]["UserName"]
            itchat.send(content, toUserName=temp_info)

    def data_analysis(self):
        """
        数据分析返回结果
        :return:
        """
        importance_province = "陕西"  # 你所在的省市(注意数据库里是否有此数据)
        importance_city = "西安"  # 你所在的城市(同上) result中的需要自己修改
        result = "您好!\n我是你的智能疫情监控机器人ABL\n现在是北京时间: %s %s\n%s\n在十二小时内\n全国内陆" \
                 "30个地区:\n总病例:%s\n全国新增病例:%s\n西安新增病例:%s 积累病例:%s\n陕西积累病例:%s\n下面是新增疫情详细数据:%s疫情期间,注意保护好自己和家" \
                 "人的健康\n如什么问题可以问我哦"  # 时间 天气 昨天时间 今日时间 疫情数据
        coon = pymysql.connect(host=self.host_ip, user=self.host_user, password="963369", database="epidemic_data",
                               charset="utf8")
        number = pd.read_sql("select cycle from all_data order by id DESC limit 1", coon)["cycle"].to_list()[0]
        data1 = pd.read_sql("select * from all_data where cycle = %s" % number, coon)
        data2 = pd.read_sql("select * from all_data where cycle = %s" % (int(number) - 1), coon)
        now_time = data1.date_info.unique()[0] + " " + data1.detail_time.unique()[0]  # 查询数据收集时间
        week_info = self.get_week_day(datetime.date.today())
        weather = self.get_window()  # 天气数据
        all_num = data1["confirmedCount"].sum()  # 目前总人数
        add_all_num = data1["confirmedCount"].sum() - data2["confirmedCount"].sum()  # 总新增人数

        sx_all = data1[data1["province_name"] == importance_province]["confirmedCount"].sum()
        add_xian = int(data1[data1["cityName"] == importance_city]["confirmedCount"]) - \
                   int(data2[data2["cityName"] == importance_city]["confirmedCount"])  # 西安新增人数
        xian_all = int(data1[data1["cityName"] == importance_city]["confirmedCount"])

        temp_a1 = data1.groupby("province_name")["confirmedCount"].sum()
        temp_a2 = data2.groupby("province_name")["confirmedCount"].sum()
        add_city = (temp_a1 - temp_a2).sort_values(ascending=False)
        add_city = add_city[add_city.values != 0]  # 新增地区及人数
        result_str = "\n"
        for city_name, number in zip(add_city.index.tolist(), add_city.values.tolist()):
            str_data = str(city_name) + "新增病例: " + str(number) + "\n"
            result_str += str_data

        danger_area = data2.groupby("province_name")["confirmedCount"].sum().sort_values(ascending=False)[: 10]
        danger_str = "\n"  # 疫情严重地区可以自己添加
        for city_name, number in zip(danger_area.index.tolist(), danger_area.values.tolist()):
            str_data = str(city_name) + "出现病例: " + str(number) + "\n"
            danger_str += str_data

        result = result % (str(now_time).split(" ")[1], week_info, weather, all_num, add_all_num,
                           add_xian, xian_all, sx_all, result_str)
        coon.close()
        return result

    @staticmethod
    def get_week_day(date):
        week_day = {
            0: '星期一',
            1: '星期二',
            2: '星期三',
            3: '星期四',
            4: '星期五',
            5: '星期六',
            6: '星期日',
        }
        day = date.weekday()  # weekday()可以获得是星期几
        return week_day[day]

    @staticmethod
    def get_window():
        url = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=%E8%A5%BF%E5%AE%89%E5%A4%A9%E6%B0%94"
        response = requests.get(url)
        content = json.loads(response.content.decode())
        if content["result"]:
            return "未获取到天气信息"
        else:
            return content["content"]


if __name__ == '__main__':
    # itchat.auto_login(hotReload=True, enableCmdQR=2)  # 如果你打算部署到服务器上,请使用这行代码,注释掉下面那行
    itchat.auto_login(hotReload=True)
    sup = VirusSupervise()
    sup.start()
    itchat.run()
  • 下面介绍需要修改到地方:
    在这里插入图片描述
    print_content() 这个函数是负责接受消息和自动回复消息,你需要向 for 循环到那个列表里,添加允许加入自动聊天人到微信名,就是谁给发消息需要机器人来给他回复,里面有他到微信名,注意是微信名,程序会自动回复消息,如果没有就不会做处理
    在这里插入图片描述
    send_msg() 这个模块是用来发送数据报告的,name_list 这里是你希望给哪些微信好友每天定时发送数据报告,将他们的“微信备注名”填写到列表里。
    在这里插入图片描述
    importance_province = “陕西” # 你所在的省市(注意数据库里是否有此数据)
    importance_city = “西安” # 你所在的城市(同上) result中的需要自己修改

如果感兴趣到话,可以自己试试,如果还没有看这个系列的前两篇文章,请先按前两篇文章的内容来操作,有问题欢迎交流!点个赞吧

评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值