查询全球疫情app
设计思想:首先需要在网站上爬取全球的的疫情信息,需要运用Python语言并且使用pycharm来连接MySQL数据库,讲爬取到的疫情信息存到数据库中去,代码如下:
1 import pymysql 2 import requests 3 import json 4 # 放入要爬的url 5 url = "https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5" 6 # 设置header做一个防爬机制 7 header = {"user-agent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36"} 8 # 获取response的json 9 response = requests.get(url, headers=header) 10 # 取得数据词典 11 data = json.loads(response.content.decode()) 12 data_str = data['data'] 13 data_json = json.loads(data_str) 14 # 连接数据库 15 db = pymysql.connect(host = 'localhost', port=3306, user='root', password='20183602', db='yiqing', charset='utf8') 16 #使用cursor方法生成一个游标 17 cursor = db.cursor() 18 confirmed_total = 0 19 suspected_total = 0 20 dead_total = 0 21 healed_total = 0 22 # 更新时间 23 lastUpdateTime = data_json['lastUpdateTime'] 24 # 取出各个国家的数据 25 for worldData in data_json['areaTree']: 26 countryName = worldData['name'] 27 confirmed = worldData['total']['confirm'] 28 confirmed_total += confirmed 29 suspected = worldData['total']['suspect'] 30 suspected_total += suspected 31 dead = worldData['total']['dead'] 32 dead_total += dead 33 healed = worldData['total']['heal'] 34 healed_total += healed 35 sql = "insert into worlddata(id,countryname,confirmed,suspected,dead,healed,lastupdateTime) values({},'{}','{}','{}','{}', '{}','{}')".format(0, countryName, confirmed, suspected, dead, healed, lastUpdateTime) 36 cursor.execute(sql) 37 db.commit() 38 sql_total = "insert into worlddata(id,countryname,confirmed,suspected,dead,healed,lastupdateTime) values({},'{}','{}','{}','{}', '{}','{}')".format(0, 0, confirmed_total, suspected_total, dead_total, healed_total, lastUpdateTime) 39 cursor.execute(sql_total) 40 db.commit()
数据库截图:
然后是使用Android studio软件来制作一个APP,设置app界面的代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:orientation="vertical" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <Spinner 11 android:id="@+id/condition" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 /> 15 <EditText 16 android:id="@+id/et_content" 17 android:layout_width="180dp" 18 android:layout_height="40dp" 19 android:layout_toRightOf="@+id/condition" 20 /> 21 <Button 22 android:id="@+id/bt_send" 23 android:layout_width="match_parent" 24 android:layout_height="wrap_content" 25 android:text="查询" 26 android:layout_toRightOf="@+id/et_content" 27 /> 28 29 <ListView 30 android:id="@+id/lv" 31 android:layout_width="match_parent" 32 android:layout_height="match_parent" 33 android:layout_marginTop="50dp" 34 /> 35 36 </RelativeLayout>
然后根据数据库中的数据格式建立一个存放全球数据信息的data文件,代码如下:
1 1 package com.example.yiqing; 2 2 3 3 public class WorldData { 4 4 private int id; 5 5 private String countryname; 6 6 private String confirmed; 7 7 private String suspected; 8 8 private String dead; 9 9 private String healed; 10 10 private String lastUpdateTime; 11 11 12 12 13 13 public int getId() { 14 14 return id; 15 15 } 16 16 17 17 public void setId(int id) { 18 18 this.id = id; 19 19 } 20 20 21 21 public String getCountryname() { 22 22 return countryname; 23 23 } 24 24 25 25 public void setCountryname(String countryname) { 26 26 this.countryname = countryname; 27 27 } 28 28 29 29 public String getConfirmed() { 30 30 return confirmed; 31 31 } 32 32 33 33 public void setConfirmed(String confirmed) { 34 34 this.confirmed = confirmed; 35 35 } 36 36 37 37 public String getSuspected() { 38 38 return suspected; 39 39 } 40 40 41 41 public void setSuspected(String suspected) { 42 42 this.suspected = suspected; 43 43 } 44 44 45 45 public String getDead() { 46 46 return dead; 47 47 } 48 48 49 49 public void setDead(String dead) { 50 50 this.dead = dead; 51 51 } 52 52 53 53 public String getHealed() { 54 54 return healed; 55 55 } 56 56 57 57 public void setHealed(String healed) { 58 58 this.healed = healed; 59 59 } 60 60 61 61 public String getLastUpdateTime() { 62 62 return lastUpdateTime; 63 63 } 64 64 65 65 public void setLastUpdateTime(String lastUpdateTime) { 66 66 this.lastUpdateTime = lastUpdateTime; 67 67 } 68 68 }
然后需要把数据库中的疫情信息读取出来,所以要创建一个连接数据库的Java文件并可以通过IP地址访问,该文件中还要实现对数据库里面的数据的调用与查询,代码如下:
1 package com.example.yiqing; 2 3 4 import java.sql.Connection; 5 import java.sql.DriverManager; 6 import java.sql.PreparedStatement; 7 import java.sql.ResultSet; 8 import java.sql.SQLException; 9 import java.util.ArrayList; 10 import java.util.HashMap; 11 import java.util.List; 12 13 public class DBOpenHelper { 14 private static String driver = "com.mysql.jdbc.Driver"; 15 private static String url = "jdbc:mysql://192.168.0.123:3306/yiqing?characterEncoding=utf-8"; 16 private static String user = "root";//用户名 17 private static String password = "20183602";//密码 18 19 public static Connection getConn(){ 20 Connection conn = null; 21 try { 22 Class.forName(driver); 23 conn = (Connection) DriverManager.getConnection(url,user,password);//获取连接 24 } catch (ClassNotFoundException e) { 25 e.printStackTrace(); 26 } catch (SQLException e) { 27 e.printStackTrace(); 28 } 29 return conn; 30 } 31 public static List<WorldData> searchDataByCountry(String condition,String country_name){ 32 List<WorldData> list = new ArrayList<>(); 33 Connection connection = getConn(); 34 String sql = ""; 35 //System.out.println(condition); 36 if(condition.equals("国家")){ 37 sql = "select * from worlddata where countryname like ?"; 38 } 39 if(condition.equals("时间")){ 40 sql = "select * from worlddata where lastUpdateTime like ?"; 41 } 42 System.out.println(country_name); 43 if(connection !=null){ 44 try { 45 PreparedStatement ps = connection.prepareStatement(sql); 46 if(ps!=null){ 47 ps.setString(1,"%"+country_name+"%"); 48 ResultSet rs = ps.executeQuery(); 49 if(rs!=null){ 50 while(rs.next()){ 51 WorldData worldData = new WorldData(); 52 worldData.setId(rs.getInt("id")); 53 worldData.setCountryname(rs.getString("countryname")); 54 worldData.setConfirmed(rs.getString("confirmed")); 55 worldData.setSuspected(rs.getString("suspected")); 56 worldData.setDead(rs.getString("dead")); 57 worldData.setHealed(rs.getString("healed")); 58 worldData.setLastUpdateTime(rs.getString("lastUpdateTime")); 59 list.add(worldData); 60 } 61 connection.close(); 62 ps.close(); 63 return list; 64 }else{ 65 return null; 66 } 67 }else{ 68 return null; 69 } 70 } catch (SQLException e) { 71 e.printStackTrace(); 72 return null; 73 } 74 }else{ 75 return null; 76 } 77 78 } 79 }
然后就是在MainActivity文件中编写用到的方法并且调用对数据库的操作的函数,实现把从数据库中查询到的数据显示出来,代码如下:
1 package com.example.yiqing; 2 3 import androidx.appcompat.app.AppCompatActivity; 4 5 import androidx.appcompat.app.AppCompatActivity; 6 7 import android.annotation.SuppressLint; 8 import android.app.Activity; 9 import android.icu.lang.UCharacter; 10 import android.os.Bundle; 11 import android.os.Handler; 12 import android.os.Message; 13 import android.text.Editable; 14 import android.text.TextWatcher; 15 import android.view.View; 16 import android.widget.AdapterView; 17 import android.widget.ArrayAdapter; 18 import android.widget.Button; 19 import android.widget.EditText; 20 import android.widget.ListView; 21 import android.widget.Spinner; 22 import android.widget.TextView; 23 24 import java.sql.Connection; 25 import java.sql.ResultSet; 26 import java.sql.Statement; 27 import java.util.ArrayList; 28 import java.util.List; 29 30 public class MainActivity extends AppCompatActivity { 31 private Button bt_send; 32 private EditText et_content; 33 private static final int TEST_USER_SELECT = 1; 34 private String content; 35 private Spinner conditionSpinner; 36 private String condition; 37 private ListView lv; 38 String[] strs = new String[]{}; 39 @SuppressLint("HandlerLeak") 40 private Handler mHandler = new Handler(){ 41 @Override 42 public void handleMessage(Message msg){ 43 44 switch(msg.what){ 45 case TEST_USER_SELECT: 46 String s = (String)msg.obj; 47 //System.out.println("***********"); 48 // System.out.println("***********"); 49 //System.out.println("data:"+s); 50 strs = s.split(" "); 51 lv.setAdapter(new ArrayAdapter<String>(MainActivity.this,R.layout.support_simple_spinner_dropdown_item,strs)); 52 break; 53 } 54 } 55 }; 56 57 @Override 58 protected void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 setContentView(R.layout.activity_main); 61 bt_send = findViewById(R.id.bt_send); 62 et_content = findViewById(R.id.et_content); 63 et_content.addTextChangedListener(new TextWatcher() { 64 @Override 65 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 66 67 } 68 69 @Override 70 public void onTextChanged(CharSequence s, int start, int before, int count) { 71 72 } 73 74 @Override 75 public void afterTextChanged(Editable s) { 76 content = s.toString(); 77 } 78 }); 79 conditionSpinner = findViewById(R.id.condition); 80 final String [] data = {"国家","时间"}; 81 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,data); 82 conditionSpinner.setAdapter(adapter); 83 conditionSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ 84 85 @Override 86 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 87 //取得选中的值 88 condition = data[position]; 89 //设置显示当前选择的项 90 parent.setVisibility(View.VISIBLE); 91 } 92 93 @Override 94 public void onNothingSelected(AdapterView<?> parent) { 95 96 } 97 }); 98 System.out.println(condition); 99 lv = findViewById(R.id.lv); 100 101 } 102 @Override 103 protected void onStart(){ 104 super.onStart(); 105 bt_send.setOnClickListener(new View.OnClickListener() { 106 @Override 107 public void onClick(View v) { 108 //执行查询操作 109 //连接数据库进行操作需要在主线程操作 110 new Thread(new Runnable() { 111 @Override 112 public void run() { 113 //调用数据库帮助类中的方法取数据 114 List<WorldData> list = DBOpenHelper.searchDataByCountry(condition,content); 115 Message message = mHandler.obtainMessage(); 116 String s = ""; 117 for(int i=0;i<list.size();i++){ 118 s += "时间:"+list.get(i).getLastUpdateTime()+" "; 119 s += list.get(i).getCountryname()+"确诊人数为: "; 120 s += list.get(i).getConfirmed()+" "; 121 } 122 message.what = TEST_USER_SELECT; 123 message.obj = s; 124 mHandler.sendMessage(message); 125 } 126 }).start(); 127 } 128 }); 129 } 130 }
最后通过选择地点或时间的方式来查询疫情信息,结果截图: