zoukankan      html  css  js  c++  java
  • 疫情信息爬取及可视化 app

    一、要求

    1、要求开发一款移动端的全世界疫情实时查询系统。

    2、要求将前两周的项目合并为一个完整的项目。 采用统一的数据库。(建议MySQL数据库)

    3、实现从数据采集、数据存储、数据查询(WEB端和移动端)一体全世界实时疫情查询系统。

    4、以本机数据库为服务器端,web端和移动端连接远程数据库实现数据共享,要求数据库表格式统一化。

    5、查询显示当前最新时间的数据,可以查询任一时间任一地点的数据。该系统要求在服务器端发布,可以通过IP地址访问。

    二、设计思路

    1、数据准备,使用python从网上爬取疫情各地的数据,并存入mysql数据库

    2、数据展示,遇到了很大的难题:(Android获取数据时,连不上数据库)按照老师要求我的解决方法是从Android发送http请求到web端web端在从数据库获取数据,以此来做到web端和我Android端公用一套数据。

     3、使用volley的stringrequest向web请求数据(json)

     4、使用Gson进行数据转换。

     5、使用MPAndroidChart的柱状图来进行数据可视化

    三、psp表

     

     日期  开始时间  结束时间  中断时间  净时间  活动  备注
     2020-3-17      15:18  15:36  3分钟  22分钟

    更新上周所爬取的内容并爬取其他各国的数据

     比较容易
     15:37  19:46  10分钟  239  尝试在Android中直接连接mysql数据库  失败,被迫放弃!
     19:47  21:35   108分钟

    学习okhttp的发送网络请求的方法

    https://www.jianshu.com/p/5bc65d66a4b2

    学习volley的发送网络请求的方法

    https://www.cnblogs.com/lizhanqi/p/5712581.html

    1、okhttp实现向自己的电脑发送请求失败

    2、volley的stringrequest实现向自己的电脑发送请求成功

     21:36  22:56  20分钟  60分钟  实现web端的查询和对应的Android 的请求的响应

    因为8G内存承受不了web+Android+模拟器一起运行,

    调试很麻烦。哎!

     23:15  23:40 5分钟   20分钟  实现Android的UI界面  基础知识忘得差不多了!
     2020-03-18  0:05  1:00  10分钟  45分钟   完成控件绑定,发送请求、事件监听等逻辑代码  自己写的很少,很多样板代码和复制粘贴。。。
    1:05 2:10 5分钟 60分钟 调试改错

    有关发送网络请求的程序,请求失败不要急着改代码,

    因为有可能是网络不好、、、(我就是)

    9:50  13:17 30分钟 177分钟

    学习 MPAndroidChart图表

    https://www.jianshu.com/p/76de8cea75ae

    实现数据可视化展示

    新知识不好学啊!!!

    四、遇到的问题

    1、Android获取数据时,连不上数据库(未解决)

    导包无误:

     

    编译可以通过,驱动是 Class.forName("com.mysql.cj.jdbc.Driver");就是连不上。

     针对这个问题研究了3个多小时,最后我放弃了!哎!

    2、MPAndroidChart可视化 x 轴 显示是字符串及地区名(默认是float)

    解决方法:

    第一步:重新 ValueFormatter 类

    package com.me.http;
    
    import com.github.mikephil.charting.components.AxisBase;
    import com.github.mikephil.charting.components.XAxis;
    import com.github.mikephil.charting.formatter.ValueFormatter;
    
    import java.text.DecimalFormat;
    
    public class MyValueFormatter extends ValueFormatter{
        private final DecimalFormat mFormat;
        private String suffix;
        private String [] str;
    
        public MyValueFormatter(String suffix,String [] str) {
            mFormat = new DecimalFormat("0000");
            this.suffix = suffix;
            this.str = str;
        }
    
        @Override
        public String getFormattedValue(float value) {
            return mFormat.format(value) + suffix;
        }
    
        @Override
        public String getAxisLabel(float value, AxisBase axis) {
            if (axis instanceof XAxis) {
                return str[(int)value];
            } else if (value > 0) {
                return mFormat.format(value) + suffix;
            } else {
                return mFormat.format(value);
            }
        }
    }
    View Code

    第二步:准备String数组(地区名数组)

     viewModel = ViewModelProviders.of(requireActivity()).get(ViewModel.class);
            list = viewModel.getList();
            for (int i = 0; i < 7; i++) {
                str[i] = list.get(i).getName();
            }
    View Code

    第三步:准备实体时将与前准备的String数组下标和与之对应的数据存入

    ArrayList<BarEntry> values = new ArrayList<>();
            for (int i = 0; i < 7; i++) {
                BarEntry barEntry = new BarEntry(i,Float.valueOf(list.get(i).getConfirm()));
                values.add(barEntry);
            }
    View Code

    第四部:使用自己的ValueFormatter 设置 x 轴所显示的数据

     ValueFormatter custom = new MyValueFormatter(" 1",str);
    xAxis.setValueFormatter(custom);
    View Code

    五、源代码

    1、python爬取中国各省市数据

    import requests
    import json
    from pymysql import *
    import requests
    from retrying import retry
    headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36"
                ,"Referer": "https://wp.m.163.com/163/page/news/virus_report/index.html?_nw_=1&_anw_=1"}
    
    
    def _parse_url(url):
        response = requests.get(url,headers=headers,timeout=3) #3秒之后返回
        return response.content.decode()
    
    
    def parse_url(url):
        try:
            html_str = _parse_url(url)
        except:
            html_str = None
        return html_str
    
    
    class yiqing:
        f = 0
    
        url="https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=316765429316"
    
        def getContent_list(self,html_str):
            dict_data = json.loads(html_str)
            #各省的数据
            content_list = dict_data["data"]
            
            return content_list
    
        
        def saveContent_list(self,i):
            # 打开数据库连接(ip/数据库用户名/登录密码/数据库名)
            con = connect("localhost", "root", "root", "text")
            # 使用 cursor() 方法创建一个游标对象 cursor
            cursors = con.cursor()
            # 使用 execute()  方法执行 SQL 查询 返回的是你影响的行数
            if self.f ==0 :
                cursors.execute("delete from citys")
                cursors.execute("delete from provinces")
                self.f = self.f+1
            row = cursors.execute("insert into provinces values(%s,%s,%s,%s,%s,%s,%s,%s)",
                                  (i.get('id'),i.get('name'),i.get('total').get('confirm'),
                                   i.get('total').get('suspect'),i.get('total').get('heal'),
                                   i.get('total').get('dead'),i.get('total').get('severe'),
                                   i.get('lastUpdateTime')))
            province = i.get('name')
            for j in i.get('children'):
                row = cursors.execute("insert into citys (id,name,confirm,suspect,heal,dead,severe,lastUpdateTime,province) values(%s,%s,%s,%s,%s,%s,%s,%s,%s)",
                                  (j.get('id'),j.get('name'),j.get('total').get('confirm'),
                                   j.get('total').get('suspect'),j.get('total').get('heal'),
                                   j.get('total').get('dead'),j.get('total').get('severe'),
                                   j.get('lastUpdateTime'),province))
            con.commit()#提交事务
            con.close()# 关闭数据库连接
    
            
        def run(self): #实现主要逻辑
            #请求数据
            html_str = parse_url(self.url)
            #获取数据
            content_list = self.getContent_list(html_str)
            values = content_list["areaTree"][0]["children"]
            for i in values:
                self.saveContent_list(i)
    
    if __name__ == '__main__':
        yq = yiqing()
        yq.run()
        print('爬取,存储成功!!')
    View Code

    2、python爬取其他各国数据

    import requests
    import json
    from pymysql import *
    import requests
    from retrying import retry
    headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36"
                ,"Referer": "https://wp.m.163.com/163/page/news/virus_report/index.html?_nw_=1&_anw_=1"}
    
    
    def _parse_url(url):
        response = requests.get(url,headers=headers,timeout=3) #3秒之后返回
        return response.content.decode()
    
    
    def parse_url(url):
        try:
            html_str = _parse_url(url)
        except:
            html_str = None
        return html_str
    
    
    class yiqing:
        f = 0
    
        url="https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=316765429316"
    
        def getContent_list(self,html_str):
            dict_data = json.loads(html_str)
            #各省的数据
            content_list = dict_data["data"]
            
            return content_list
    
        
        def saveContent_list(self,i):
            # 打开数据库连接(ip/数据库用户名/登录密码/数据库名)
            con = connect("localhost", "root", "root", "text")
            # 使用 cursor() 方法创建一个游标对象 cursor
            cursors = con.cursor()
            # 使用 execute()  方法执行 SQL 查询 返回的是你影响的行数
            if self.f ==0 :
                cursors.execute("delete from world")
                self.f = self.f+1
            row = cursors.execute("insert into world values(%s,%s,%s,%s,%s,%s,%s,%s)",
                                  (i.get('id'),i.get('name'),i.get('total').get('confirm'),
                                   i.get('total').get('suspect'),i.get('total').get('heal'),
                                   i.get('total').get('dead'),i.get('total').get('severe'),
                                   i.get('lastUpdateTime')))
            
            con.commit()#提交事务
            con.close()# 关闭数据库连接
    
            
        def run(self): #实现主要逻辑
            #请求数据
            html_str = parse_url(self.url)
            #获取数据
            content_list = self.getContent_list(html_str)
            values = content_list["areaTree"]
            for i in values:
                self.saveContent_list(i)
    
    if __name__ == '__main__':
        yq = yiqing()
        yq.run()
        print('爬取,存储成功!!')
    View Code

    3、Android工程的github地址:https://github.com/xiaotian12-call/yiqing_app

    六、运行测试

     

  • 相关阅读:
    团队项目冲刺第五天
    团队项目冲刺第四天
    团队项目冲刺第三天
    团队项目冲刺第二天
    团队项目冲刺第一天
    团队任务命题
    java报错the superclass was not found 解决方案
    Buildings 分类: ACM 多校 2015-07-23 22:09
    1009 数字1的数量 分类: 51nod 2015-07-20 21:44 3人阅读 评
    1284 2 3 5 7的倍数 分类: 51nod 2015-07-18 22:06 6人阅读
  • 原文地址:https://www.cnblogs.com/20183544-wangzhengshuai/p/12517681.html
Copyright © 2011-2022 走看看