全球疫情爬取-移动端:
一、项目要求:
二、 项目思路:
1.准备数据:使用pythone将数据存放到mysql中
2.将android连接数据库mysql,通过导包和更改自己的ip地址
3.进行信息读取,查询,移动端app显示
三、导包:
1.在main目录下新建文件夹libs,将自己的jar包复制进入,然后右键选择 Add As Library 进行导入;
四、 项目结构:
五、相关源码:
DBOpenHelper.java:
package com.example.myapplication; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class DBOpenHelper { private static String driver = "com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql://192.168.1.107:3306/database?characterEncoding=utf-8"; private static String user = "root";//用户名 private static String password = "20000604";//密码 public static Connection getConn(){ Connection conn = null; try { Class.forName(driver); conn = (Connection) DriverManager.getConnection(url,user,password);//获取连接 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } public static List<WorldData> searchDataByCountry(String condition,String country_name){ List<WorldData> list = new ArrayList<>(); Connection connection = getConn(); String sql = ""; //System.out.println(condition); if(condition.equals("时间")){ sql = "select * from worlddata where lastupdateTime like ?"; } if(condition.equals("国家")){ sql = "select * from worlddata where countryname like ?"; } System.out.println(country_name); if(connection !=null){ try { PreparedStatement ps = connection.prepareStatement(sql); if(ps!=null){ ps.setString(1,"%"+country_name+"%"); ResultSet rs = ps.executeQuery(); if(rs!=null){ while(rs.next()){ WorldData worldData = new WorldData(); worldData.setId(rs.getInt("id")); worldData.setCountryname(rs.getString("countryname")); worldData.setConfirmed(rs.getString("confirmed")); worldData.setSuspected(rs.getString("suspected")); worldData.setDead(rs.getString("dead")); worldData.setHealed(rs.getString("healed")); worldData.setLastupdateTime(rs.getString("lastupdateTime")); list.add(worldData); } connection.close(); ps.close(); return list; }else{ return null; } }else{ return null; } } catch (SQLException e) { e.printStackTrace(); return null; } }else{ return null; } } }
MainActivity.java:
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.app.Activity; import android.icu.lang.UCharacter; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private Button bt_send; private EditText et_content; private static final int TEST_USER_SELECT = 1; private String content; private Spinner conditionSpinner; private String condition; private ListView lv; String[] strs = new String[]{}; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg){ switch(msg.what){ case TEST_USER_SELECT: String s = (String)msg.obj; //System.out.println("***********"); // System.out.println("***********"); //System.out.println("data:"+s); strs = s.split(" "); lv.setAdapter(new ArrayAdapter<String>(MainActivity.this,R.layout.support_simple_spinner_dropdown_item,strs)); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt_send = findViewById(R.id.bt_send); et_content = findViewById(R.id.et_content); et_content.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { content = s.toString(); } }); conditionSpinner = findViewById(R.id.condition); final String [] data = {"时间","国家"}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,data); conditionSpinner.setAdapter(adapter); conditionSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //取得选中的值 condition = data[position]; //设置显示当前选择的项 parent.setVisibility(View.VISIBLE); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); System.out.println(condition); lv = findViewById(R.id.lv); } @Override protected void onStart(){ super.onStart(); bt_send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //执行查询操作 //连接数据库进行操作需要在主线程操作 new Thread(new Runnable() { @Override public void run() { //调用数据库帮助类中的方法取数据 List<WorldData> list = DBOpenHelper.searchDataByCountry(condition,content); Message message = mHandler.obtainMessage(); String s = ""; for(int i=0;i<list.size();i++){ s+=" "; s += "时间:"+list.get(i).getLastupdateTime()+" "; s += list.get(i).getCountryname()+"确诊人数为:"+list.get(i).getConfirmed()+" "; // s += list.get(i).getConfirmed()+" "; s += "治愈人数:"+list.get(i).getHealed()+" "; s += "死亡人数:"+list.get(i).getDead()+" "; } message.what = TEST_USER_SELECT; message.obj = s; mHandler.sendMessage(message); } }).start(); } }); } }
WorldData.java:
package com.example.myapplication; public class WorldData { private int id; private String countryname; private String confirmed; private String suspected; private String dead; private String healed; private String lastupdateTime; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCountryname() { return countryname; } public void setCountryname(String countryname) { this.countryname = countryname; } public String getConfirmed() { return confirmed; } public void setConfirmed(String confirmed) { this.confirmed = confirmed; } public String getSuspected() { return suspected; } public void setSuspected(String suspected) { this.suspected = suspected; } public String getDead() { return dead; } public void setDead(String dead) { this.dead = dead; } public String getHealed() { return healed; } public void setHealed(String healed) { this.healed = healed; } public String getLastupdateTime() { return lastupdateTime; } public void setLastupdateTime(String lastupdateTime) { this.lastupdateTime = lastupdateTime; } }
activity_xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Spinner android:id="@+id/condition" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_content" android:layout_width="180dp" android:layout_height="40dp" android:layout_toRightOf="@+id/condition" /> <Button android:id="@+id/bt_send" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查询" android:layout_marginTop="30dp"/> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="50dp" /> </RelativeLayout>
六、运行截图:
七、遇到的问题:
1.点击查询按钮时,界面进行闪退,显示mysql连接问题
解决方法:(舍友帮助)
参考博客:https://www.cnblogs.com/xjmm/p/12518798.html
时长:5h
八、PSP时间表:
阶段 | 时间 | 问题 | 备注 |
pyhone爬取世界疫情信息,存入mysql | 30min | 在之前读取全国疫情的知识储备下,这一步相对来说比较容易 | |
android连接mysql | 6h | 初次使用android连接mysql,并通过ip地址访问,问题是真的多呀 | 各种网络问题,权限问题,多种闪退问题,还不详细提示错误信息,是真的难以解决呀,不过最后在舍友的帮助下,在mysql终端下更新权限才得以解决https://www.cnblogs.com/xjmm/p/12518798.html |
android读取,查询,显示疫情信息 | 2h | 在这次的项目上,自我感觉真的是从头学,现学现卖 | 一个项目的逻辑是真的重要呀,慢慢的解决,积累错误原因,吸取经验 |