Java网页数据采集器[下篇-数据查询]【转载】
本期概述
上一期我們學習了如何將html采集到的數據存儲到MySql數據庫中,這期我們來學習下如何在存儲的數據中查詢我們實際想看到的數據.
數據采集頁面 2011-2012賽季英超球隊戰績
如果是初學者 以下可能對你有幫助
- Java如何操作MySql?
???? 在使用java 操作MySql數據庫之前 我們需要在項目文件中導入 一個jar包(mysql-connector-java-5.1.18-bin)
???? 可以在MySql官網下載 Connector/J 5.1.18
???? 第一次使用MySql?? ?請看 java連接MYSQL??????
- 如何在java項目中導入jar包?
???? 請看這個 Eclipse下如何導入jar包
- 如何安裝MySql數據庫??
???? 如果是初學者 想使用MySql數據庫的話 可以去這里 XAMPP中文官網? 下載 XAMPP 套裝
???? XAMPP(Apache+MySQL+PHP+PERL)是一個功能強大的建 XAMPP 軟件站集成軟件包,?而且一鍵式安裝,?無需修改配置文件,非常好用.??
?
關于,如何在MySql里創建數據庫,請看Java網頁數據采集器實例教程[中篇-數據存儲].
?
數據庫準備好了,我們開始寫java程序代碼;
這期,我們主要在MySql 類里增加了一個數據查看的方法 queryMySql(),并增加了一個 DataQuery類, 包含了一些比賽結果的查詢方法.
?
主程序代碼
這里簡單介紹下各個類以及包含的方法
DataCollectionAndStorage類 和里面的dataCollectAndStore() 方法 用于Html數據采集和存儲
DataCollectionAndStorage類import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
/*** DataCollectionAndStorage類 用于數據的收集和存儲* @author SoFlash - 博客園 http://www.cnblogs.com/longwu*/
public class DataCollectionAndStorage {/*** dataCollectAndStore()方法 用于Html數據收集和存儲*/public void dataCollectAndStore() {// 首先用一個字符串 來裝載網頁鏈接String strUrl = "http://www.footballresults.org/league.php?all=1&league=EngPrem";String sqlLeagues = "";try {// 創建一個url對象來指向 該網站鏈接 括號里()裝載的是該網站鏈接的路徑// 更多可以看看 http://wenku.baidu.com/view/8186caf4f61fb7360b4c6547.htmlURL url = new URL(strUrl);// InputStreamReader 是一個輸入流讀取器 用于將讀取的字節轉換成字符// 更多可以看看 http://blog.sina.com.cn/s/blog_44a05959010004il.htmlInputStreamReader isr = new InputStreamReader(url.openStream(),"utf-8"); // 統一使用utf-8 編碼模式// 使用 BufferedReader 來讀取 InputStreamReader 轉換成的字符BufferedReader br = new BufferedReader(isr);String strRead = ""; // new 一個字符串來裝載 BufferedReader 讀取到的內容// 定義3個正則 用于獲取我們需要的數據String regularDate = "(\\d{1,2}\\.\\d{1,2}\\.\\d{4})";String regularTwoTeam = ">[^<>]*</a>";String regularResult = ">(\\d{1,2}-\\d{1,2})</TD>";//創建 GroupMethod類的對象 gMethod 方便后期調用其類里的 regularGroup方法GroupMethod gMethod = new GroupMethod();//創建DataStructure數據結構 類的對象 用于數據下面的數據存儲DataStructure ds = new DataStructure();//創建MySql類的對象 用于執行MySql語句MySql ms = new MySql();int i = 0; // 定義一個i來記錄循環次數 即收集到的球隊比賽結果數int index = 0; // 定義一個索引 用于獲取分離 2個球隊的數據 因為2個球隊正則是相同的// 開始讀取數據 如果讀到的數據不為空 則往里面讀while ((strRead = br.readLine()) != null) {/*** 用于捕獲日期數據*/String strGet = gMethod.regularGroup(regularDate, strRead);// 如果捕獲到了符合條件的 日期數據 則打印出來if (!strGet.equals("")) {//System.out.println("Date:" + strGet);//將收集到的日期存在數據結構里ds.date = strGet;// 這里索引+1 是用于獲取后期的球隊數據++index; // 因為在html頁面里 源代碼里 球隊數據是在剛好在日期之后}/*** 用于獲取2個球隊的數據*/strGet = gMethod.regularGroup(regularTwoTeam, strRead);if (!strGet.equals("") && index == 1) { // 索引為1的是主隊數據// 通過subtring方法 分離出 主隊數據strGet = strGet.substring(1, strGet.indexOf("</a>"));//System.out.println("HomeTeam:" + strGet); // 打印出主隊//將收集到的主隊名稱 存到 數據結構里ds.homeTeam = strGet;index++; // 索引+1之后 為2了// 通過subtring方法 分離出 客隊} else if (!strGet.equals("") && index == 2) { // 這里索引為2的是客隊數據strGet = strGet.substring(1, strGet.indexOf("</a>"));//System.out.println("AwayTeam:" + strGet); // 打印出客隊//將收集到的客隊名稱 存到數據結構里ds.awayTeam = strGet;index = 0; //收集完客隊名稱后 需要將索引還原 用于收集下一條數據的主隊名稱}/*** 用于獲取比賽結果*/strGet = gMethod.regularGroup(regularResult, strRead);if (!strGet.equals("")) {// 這里同樣用到了substring方法 來剔除'<' 和 "</TD>" 標簽 來獲取我們想要的比賽結果strGet = strGet.substring(1, strGet.indexOf("</TD>"));//System.out.println("Result:" + strGet);ds.result = strGet; //將收集到的比賽結果存到數據結構里//System.out.println();//MySql插入語句sqlLeagues = "INSERT INTO Premiership values(\""+ ds.date + "\"," + "\"" + ds.homeTeam+ "\"," + "\"" + ds.awayTeam + "\","+ "\"" + ds.result + "\")";//調用MySql類的datatoMySql()方法 來執行 MySql插入語句ms.datatoMySql(sqlLeagues);i++; //每插入完一條記錄 i+1;System.out.println("第"+i+"條數據插入成功");}}// 當讀完數據后 記得關閉 BufferReaderbr.close();//System.out.println("共收集到" + i + "條比賽記錄");// 打印出循環次數//當數據存儲完成后 打印出 收集球隊記錄數System.out.println("數據存儲完畢,共插入數據庫"+i+"條記錄");} catch (IOException e) {// 如果出錯 拋出異常e.printStackTrace();}}
}
?
DataQuery類 里面有4個方法
- initialDataBase()?用于清空數據庫里的所有比賽數據?
- getAllTeams()??? 用于獲取當前數據庫里所有球隊的名字
- querySpecifiedTeam()?? 用于查詢具體球隊的比賽情況 (可以查看你喜歡的球隊比賽結果)
- queryByDate()? 用于查詢具體日期的比賽 (查詢某一天的比賽結果)
DataQuery 類import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
/*** DataQuery 類 用于查詢數據庫里的信息 包含了不同的方法* @author SoFlash - 博客園 http://www.cnblogs.com/longwu*/
public class DataQuery {/*** 用于清空數據庫里比賽結果*/public void initialDataBase() {String initialSql = "delete from premiership";MySql ms = new MySql();try {//MySql類里 提供了一個 刪除數據的 方法 executeUpdate()ms.datatoMySql(initialSql);System.out.println("數據庫清空成功!");} catch (Exception e) {System.out.println("數據庫清空失敗!");}}/*** 用于 獲取當前數據庫里一共有多少球隊 方便后期查看自己喜歡的球隊比賽成績* @return 所有的參與過比賽的球隊名*/public Vector<String> getAllTeams() {//使用一個向量來 存取 從數據庫中讀到的值Vector<String> vecAllTeams = new Vector<String>();String allteamsSql = "select HomeTeam,AwayTeam from premiership group by HomeTeam;";ResultSet rs = null; MySql ms = new MySql();//調用 MySql類里 查看數據的方法rs = ms.queryMySql(allteamsSql);try {//如果 ResultSet數據集里的數據不為空 則獲取相應的 數據 添加到 向量vecAllTeams里while (rs.next()) {if (!vecAllTeams.contains(rs.getString("HomeTeam")))vecAllTeams.add(rs.getString("HomeTeam"));else if (!vecAllTeams.contains(rs.getString("AwayTeam")))vecAllTeams.add(rs.getString("AwayTeam"));}} catch (SQLException e) {System.out.println(e.getMessage());e.printStackTrace();}//返回 取到的所有結果return vecAllTeams;}/*** 查看具體的球隊比賽結果* @param league* @return 具體球隊的所有比賽結果*/public Vector<String> querySpecifiedTeam(String league) {//創建一個向量 來裝載 從數據庫中 讀到的數據Vector<String> lsMatches = new Vector<String>();String specifiedTeamSql = "select * from premiership where HomeTeam ='"+ league + "' or AwayTeam ='" + league + "'";MySql ms = new MySql();ResultSet rs = null;rs = ms.queryMySql(specifiedTeamSql);try {while (rs.next()) {lsMatches.add(rs.getString("Date"));lsMatches.add(rs.getString("HomeTeam"));lsMatches.add(rs.getString("AwayTeam"));lsMatches.add(rs.getString("Result"));}} catch (SQLException e) {e.printStackTrace();}return lsMatches;}/*** 查看 某一天的 比賽結果 * @param date* @return 某一天的所有比賽結果*/public List<String> queryByDate(String date) {//使用一個 list泛型來裝載 比賽結果List<String> lsMatchesOnDate = new ArrayList<String>();String sqlDate = "SELECT * FROM premiership WHERE Date ='" + date + "'";//創建一個ResultSet數據集 用來 獲取查詢到的結果集ResultSet rs = null;MySql ms = new MySql();//調用 MySql 類里的 查看數據庫數據的方法rs = ms.queryMySql(sqlDate);try {//如果 ResultSet數據集 不為空 while (rs.next()) {//則 從ResultSet數據集 中取出 相應的 字段值 添加到 list泛型里lsMatchesOnDate.add(rs.getString("Date"));lsMatchesOnDate.add(rs.getString("HomeTeam"));lsMatchesOnDate.add(rs.getString("AwayTeam"));lsMatchesOnDate.add(rs.getString("Result"));}} catch (SQLException e) {System.out.println(e.getMessage());e.printStackTrace();}//最后 返回 取到的所有比賽數據結果return lsMatchesOnDate;}
}
DataStructure類 一個簡單的數據結構 用于收集到數據的臨時性存儲
DataStructure 類/*** DataStructure 類 一個簡單的數據結構* @author SoFlash - 博客園 http://www.cnblogs.com/longwu*/
public class DataStructure { //定義數據字段public String homeTeam;public String awayTeam;public String date;public String result;
}
?
GroupMethod類 里面包含了regularGroup() 方法 用于匹配并獲取 html的數據
GroupMethod 類import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*** GroupMethod 類 用于匹配和抓取 html頁面的數據* @author SoFlash - 博客園 http://www.cnblogs.com/longwu*/
public class GroupMethod {// 傳入2個字符串參數 一個是pattern(我們使用的正則) 另一個matcher是html源代碼public String regularGroup(String pattern, String matcher) {Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(matcher);if (m.find()) { // 如果讀到return m.group();// 返回捕獲的數據} else {return ""; // 否則返回一個空字符串}}
}
? MySql類 里面含有2個方法
- datatoMySql() 方法 用于向數據庫里插入數據?
- queryMySql() 方法 用于查看數據庫里存儲的數據
MySql 類import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;/*** MySql類用于實施MySql數據庫操作* @author SoFlash - 博客園 http://www.cnblogs.com/longwu*/
public class MySql {// 定義MySql驅動,數據庫地址,數據庫用戶名 密碼, 執行語句和數據庫連接public String driver = "com.mysql.jdbc.Driver";public String url = "jdbc:mysql://127.0.0.1:3306/htmldatacollection";public String user = "root";public String password = "root";public Statement stmt = null;public Connection conn = null;/*** 創建一個插入數據的方法 executeUpdate()* @param insertSQl*/public void datatoMySql(String insertSQl) {try {try {Class.forName(driver).newInstance();} catch (Exception e) {System.out.println("無法找到驅動器");e.printStackTrace();}// 創建連接conn = DriverManager.getConnection(url, user, password);// 創建一個 Statement 對象來將 SQL 語句發送到數據庫stmt = conn.createStatement();// 執行SQL 插入語句stmt.executeUpdate(insertSQl);// 執行完 停止執行語句stmt.close();// 執行完關閉數據庫連接conn.close();} catch (Exception e) {System.out.println(e.getMessage());e.printStackTrace();}}/*** 創建一個用于select查看數據的方法 executeQuery();* @param strSelect* @return ResultSet*/public ResultSet queryMySql(String strSelect) {// 創建一個數據集 用于獲取查詢到的行數據ResultSet rs = null;try {Class.forName(driver).newInstance();} catch (Exception e) {System.out.println("無法找到驅動器!");e.printStackTrace();}try {// 創建連接conn = DriverManager.getConnection(url, user, password);// 創建一個 Statement 對象來將 SQL 語句發送到數據庫stmt = conn.createStatement();// 執行查詢語句 獲取ResultSet對象rs = stmt.executeQuery(strSelect);} catch (SQLException e) {System.out.println(e.getMessage());e.printStackTrace();}//返回結果集return rs;}
}
Main 主函數 用于數據輸出
?
Main 主函數import java.util.List;
import java.util.Scanner;
import java.util.Vector;
/*** Main 主函數 用于數據的輸出* @author SoFlash - 博客園 http://www.cnblogs.com/longwu*/
public class Main {public static void main(String[] args) {DataCollectionAndStorage dcs = new DataCollectionAndStorage();DataQuery dQuery = new DataQuery();while (true) {System.out.println("清空數據庫-請按1");System.out.println("收集英超比賽數據-請按2");System.out.println("查看英超所有球隊-請按3");System.out.println("查看具體球隊比賽結果-請按4");System.out.println("查看某一天的比賽-請按5");// Scanner 文本掃描器 用于讀取 用戶的輸入 Scanner sc = new Scanner(System.in);int intInput = sc.nextInt();if (intInput == 1) {dQuery.initialDataBase();System.out.println("---------------------------------------------");} else if (intInput == 2) {dcs.dataCollectAndStore();System.out.println("---------------------------------------------");} else if (intInput == 3) {//獲取 查詢到的所有球隊名稱Vector<String> vecAllTeams = dQuery.getAllTeams();if (vecAllTeams.size() != 0) {System.out.println("參加過比賽的球隊如下:");System.out.print("-----------------------------------------------");System.out.print("-----------------------------------------------\r\n");for (int i = 0; i < vecAllTeams.size(); i++) {if (i % 7 == 0 && i != 0) {System.out.println("\r\n");}System.out.print(vecAllTeams.get(i) + "\t");}} elseSystem.out.print("數據庫目前沒有數據,請按2收集數據!");System.out.print("\r\n---------------------------------------------");System.out.println("-----------------------------------------------\r\n");} else if (intInput == 4) {System.out.println("請輸入你要查看的球隊");Scanner scLeague = new Scanner(System.in);String strLeague = scLeague.next();//獲取 具體球隊的比賽結果Vector<String> lsResult = dQuery.querySpecifiedTeam(strLeague);if (lsResult.size() != 0) {System.out.println("日期\t\t\t主隊\t\t客隊\t\t比分");for (int i = 0; i < lsResult.size(); i++) {if (i % 4 == 0 && i != 0)System.out.println();System.out.print(lsResult.get(i) + "\t\t");}} elseSystem.out.println("沒有相關球隊的記錄或數據庫沒有數據!");System.out.println("\r\n---------------------------------------------------");} else if (intInput == 5) {System.out.println("請輸入你要查看的比賽日期 例子格式[14.01.2012]");Scanner scDate = new Scanner(System.in);String strDate = scDate.next();//獲取具體日期下的 所有比賽List<String> lsResulOnDate = dQuery.queryByDate(strDate);if (lsResulOnDate.size() != 0) {System.out.println("日期\t\t\t主隊\t\t客隊\t\t比分");for (int i = 0; i < lsResulOnDate.size(); i++) {if (i % 4 == 0 && i != 0)System.out.println();System.out.print(lsResulOnDate.get(i) + "\t\t");}} elseSystem.out.println("該天沒有比賽 或 數據庫沒有數據!");System.out.println("\r\n---------------------------------------------------");}}}
}
?
?
?
運行程序
?
?輸入1 清空數據
?
輸入2 開始收集數據 并存入數據庫 - 初始階段
?
開始收集數據 并存入數據庫 ?- 結束階段
?
輸入3 查看所有參與過比賽的球隊
?
輸入4? 再輸入要查看的具體球隊 這里查看的是 Swansea
?
輸入5? 再輸入查看具體的日期 這里是 02.01.2012
?
?
?輸入1 我們測試下清空數據的效果 這里顯示清空成功
?
輸入3 查看下是否 真正在數據庫中成功清空數據 ? 結果顯示 數據庫目前沒有數據
這樣,我們的數據查詢功能也做好了
原文地址:http://www.cnblogs.com/longwu/archive/2012/01/21/2328395.html
轉載于:https://www.cnblogs.com/dekevin/p/3574806.html
總結
以上是生活随笔為你收集整理的Java网页数据采集器[下篇-数据查询]【转载】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “君王若问妾颜色”下一句是什么
- 下一篇: 港版的三星NOTE 4或S5可以用在大陆