实时数据可视化系统的搭建(含代码)

之前一直在做别的事情,就忘记整理系统的文档了。现在正好闲下来,开始整理吧!
本系统是基于python的实时数据可视化系统。

网站如下:网站地址
该网站使用的技术和工具有:python网络爬虫、docker技术、Flask、Ajax等。
我这里爬取的是某平台的数据。代码如下:

#return:返回历史数据和当天的详细数据
import requests
import json
import time
##封装函数
def get_tencent_data():
    url_day="https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5"##当天的数据
    url_other="https://view.inews.qq.com/g2/getOnsInfo?name=disease_other"##历史数据
    header={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"}
    r_day=requests.get(url_day,headers=header)
    r_other=requests.get(url_other,headers=header)
    res_day=json.loads(r_day.text)#json字符串转化成字典
    res_other=json.loads(r_other.text)#json字符串转化成字典
    data_day=json.loads(res_day['data'])
    data_other=json.loads(res_other['data'])
    
    history={}#历史数据
    for i in data_other["chinaDayList"]:
        ds="2020."+i["date"]
        tup=time.strptime(ds,"%Y.%m.%d")
        ds=time.strftime("%Y-%m-%d",tup)#改变时间格式
        confirm=i["confirm"]
        suspect=i["suspect"]
        heal=i["heal"]
        dead=i["dead"]
        history[ds]={"confirm":confirm,"suspect":suspect,"heal":heal,"dead":dead}
    for i in data_other["chinaDayAddList"]:
        ds="2020."+i["date"]
        tup=time.strptime(ds,"%Y.%m.%d")
        ds=time.strftime("%Y-%m-%d",tup)#改变时间格式
        confirm=i["confirm"]
        suspect=i["suspect"]
        heal=i["heal"]
        dead=i["dead"]
        history[ds].update({"confirm_add":confirm,"suspect_add":suspect,"heal_add":heal,"dead_add":dead})
        
    details=[]#当日详细数据
    update_time=data_day["lastUpdateTime"]
    data_country=data_day["areaTree"]#list 25个国家
    data_province=data_country[0]["children"] #中国各省
    for pro_infos in data_province:
        province=pro_infos["name"]#各省名
        for city_infos in pro_infos["children"]:
            city=city_infos["name"]
            confirm=city_infos["total"]["confirm"]
            confirm_add=city_infos["today"]["confirm"]
            heal=city_infos["total"]["heal"]
            dead=city_infos["total"]["dead"]
            details.append([update_time,province,city,confirm,confirm_add,heal,dead])
    return history,details
get_tencent_data()

存储数据是使用docker拉取了一个mysql容器,这样可以更快的交付和部署。
存储数据:

#pymysql的简单使用
#建立连接
conn = pymysql.connect(host='111.111.111.111',
                             port=xxx,
                             user='xxx',
                             password='xxx',
                             db='xxx',
                             charset='utf8')
#创建游标,默认是元组型
cursor=conn.cursor()
sql="select * from history"
cursor.execute(sql)
res=cursor.fetchall()
print(res)
cursor.close()
conn.close()

插入数据:

#pymysql的简单使用
#建立连接
conn = pymysql.connect(host='127.0.0.1',
                             port=xxx,
                             user='xxx',
                             password='xxx',
                             db='xxx',
                             charset='utf8')
#创建游标,默认是元组型
cursor=conn.cursor()
sql="insert into history values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"
cursor.execute(sql,[time.strftime("%Y-%m-%d"),10,1,2,3,4,5,6,7])
#res=cursor.fetchall()
#print(res)
conn.commit()
cursor.close()
conn.close()

将插入数据的方法进行封装。

##更新details表
def update_details():
    cursor=None
    conn=None
    try:
        li=get_tencent_data()[1]
        #0是历史数据,1是最新数据
        conn,cursor=get_conn()
        sql="insert into details(update_time,province,city,confirm,confirm_add,heal,dead) values(%s,%s,%s,%s,%s,%s,%s)"
        sql_query='select %s=(select update_time from details order by id desc limit 1)'
        #对比当前最大时间戳
        cursor.execute(sql_query,li[0][0])
        if not cursor.fetchone()[0]:
            print(f"{time.asctime()}开始更新最新数据")
            for item in li:
                cursor.execute(sql,item)
            conn.commit()
            print(f" {time.asctime()} 更新最新数据完毕")
        else:
            print(f" {time.asctime()} 已经是最新数据!")
    except:
        traceback.print_exc()
    finally:
        close_conn(conn,cursor)

封装常用的方法:

def get_conn():
    conn = pymysql.connect(host='xxx.xxx.xxx.xxx',
                             port=xxx,
                             user='xxx',
                             password='xxxx',
                             db='xxx',
                             charset='utf8')
    #创建游标,默认是元组型
    cursor=conn.cursor()
    return conn,cursor
def close_conn(conn,cursor):
    if cursor:
        cursor.close()
    if conn:
        conn.close()

插入历史数据封装:

## 插入历史数据
def insert_history():
    cursor=None
    conn=None
    try:
        dic=get_tencent_data()[0]
        #拿到历史数据
        print(f"{time.asctime()}开始插入历史数据")
        conn,cursor=get_conn()
        sql="insert into history values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"
        for k,v in dic.items():
            cursor.execute(sql,[k,v.get("confirm"),v.get("confirm_add"),
                                   v.get("suspect"),v.get("suspect_add"),v.get("heal"),
                                v.get("heal_add"),v.get("dead"),v.get("dead_add")
                               ])
        conn.commit()
        #提交事务
        print(f"{time.asctime()}插入历史数据完毕")
    except:
        traceback.print_exc()
    finally:
        close_conn(conn,cursor)

更新历史数据封装:

##更新历史数据
def update_history():
    cursor=None
    conn=None
    try:
        dic=get_tencent_data()[0]
        print(f"{time.asctime()}开始插入历史数据")
        conn,cursor=get_conn()
        sql="insert into history values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"
        sql_query="select confirm from history where ds=%s"
        for k,v in dic.items():
            if not cursor.execute(sql_query,k):
                print(f"{time.asctime()}开始更新历史数据完毕")
                cursor.execute(sql,[k,v.get("confirm"),v.get("confirm_add"),
                                   v.get("suspect"),v.get("suspect_add"),v.get("heal"),
                                v.get("heal_add"),v.get("dead"),v.get("dead_add")
                               ])
        conn.commit()
        print(f"{time.asctime()}更新历史数据完毕")
    except:
        traceback.print_exc()
    finally:
        close_conn(conn,cursor)

爬取并存储百度的热点数据并以词云图展示出来:

def get_baidu_hot():
    """
    :return: 返回热搜
    """
    option = ChromeOptions()  # 创建浏览器实例
    option.add_argument("--headless")  # 隐藏浏览器
    option.add_argument('--no-sandbox')

    url = "https://voice.baidu.com/act/virussearch/virussearch?from=osari_map&tab=0&infomore=1"
    browser = Chrome(options=option,executable_path="./chromedriver.exe")
    browser.get(url)
    # 找到展开按钮
    dl = browser.find_element_by_css_selector('#ptab-0 > div > div.VirusHot_1-5-3_32AY4F.VirusHot_1-5-3_2RnRvg > section > div')
    dl.click()
    time.sleep(1)
    # 找到热搜标签
    c = browser.find_elements_by_xpath('//*[@id="ptab-0"]/div/div[2]/section/a/div/span[2]')
    context = [i.text for i in c]  # 获取标签内容
    print(context)
    return context


def update_hotsearch():
    """
    将热搜插入数据库
    :return:
    """
    cursor = None
    conn = None
    try:
        context = get_baidu_hot()
        print(f"{time.asctime()}开始更新热搜数据")
        conn, cursor = get_conn()
        sql = "insert into hotsearch(dt,content) values(%s,%s)"
        ts = time.strftime("%Y-%m-%d %X")
        for i in context:
            cursor.execute(sql, (ts, i))  # 插入数据
        conn.commit()  # 提交事务保存数据
        print(f"{time.asctime()}数据更新完毕")
    except:
        traceback.print_exc()
    finally:
        close_conn(conn, cursor)

上面完成了爬取xx数据,使用Flask搭建的Web应用,使用Ajax局部刷新页面数据,使用echarts制作页面的可视化模板。
完整代码见github:
代码
代码部署到服务器:
然后将代码上传到centos服务器上,这里使用gunicorn作为应用服务器。安装代码如下:

pip install gunicorn

在这里插入图片描述
这里一定要注意:一定要下载对应版本的chrome和驱动,便于成功爬取数据。
然后定时部署爬虫。
获取crontab定时调度。
crontab -l 列出当前任务。
crontab -e 编辑任务。
这里给出任务的代码:

30 * * * *  python /root/Cov/spider.py up_his  >> /root/Cov/log_his 2>&1  & 
*/5 * * * *  python /root/Cov/spider.py up_det  >> /root/Cov/log_det 2>&1  & 

你可能感兴趣的:(python)