Java提取網站后台數據進行處理並排名
一、網頁分析
截取的網站鏈接為:https://www.tiobe.com/tiobe-index/
打開網站后,可以看到這個網站的編程語言排名情況。我們選擇下圖中的圖表,這個圖表中有2001-2019年的編程語言每個月的使用率,我需要它的數據。
二、數據提取
在網頁點右鍵,點擊查看源碼:首先我們要編程把源碼下載到記事本里,看一下核心代碼
1 URL url = new URL(website); 2 // 根據鏈接(字符串格式),生成一個URL對象 3 HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 4 // 打開URL 5 BufferedReader reader =new 6 BufferedReader(new InputStreamReader(urlConnection.getInputStream(), encoding)); 7 // 得到輸入流 8 Save.saveStr("",file,false); 9 //清空記事本文件的內容 10 while ((str = reader.readLine())!= null) { 11 //每次讀取一行,放入記事本中 12 Save.saveStr(str,file,true); 13 Save.saveStr("\r\n",file,true); 14 }
下載完成后,我們打開這個文件,看一看這個文件里的內容,只截取一部分
三、數據處理
首先找到我們需要的數據(對應上圖的排名的數據),利用正則表達式將數據提取出來。
上圖是對應的數據,現在利用正則表達式來提取核心代碼如下:
1 //正則表達式要匹配的數據 2 Pattern dataCompile = Pattern.compile("Date.UTC[(]\\d{4}, \\d{1,2}, \\d{1,2}[)],\\d{1,2}.\\d{3}|name : '\\w++(\\W{0,2})? ( \\w++)(\\w++)?',data"); 3 String s; 4 try { 5 //讀入后放入記事本文檔中 6 System.out.println("處理數據中......"); 7 Save.saveStr("",file,false); 8 while ((s = in.readLine())!=null){ 9 Matcher dataNeed = dataCompile.matcher(s); 10 while (dataNeed.find()){ 11 Save.saveStr(dataNeed.group(),file,true); 12 Save.saveStr("\r\n",file,true); 13 }catch (Exception e){ 14 e.printStackTrace(); 15 }
處理完成后,打開保存的文件,可以看到一下結果,這里仍然只截取一小部分。
這個數據中有時間和使用率,這些是我繪圖所需要的,這里依然使用正則表達式將他們全部讀取出來放入一個類中。
看一下這個類的核心代碼
1 public class Data{ 2 3 private String language; //存放語言名稱 4 5 private double data; //存放使用率 6 7 private String month; //存放月 8 9 //省略字段的屬性 10 }
用這個類來存放數據,用着則表達式來提取文本中的數據,將數據放在這個類實例化的對象中。分別存放這個語言的名字和某一個時間的排名,每一個對象存放一個數據,提取后把這些對象放進10行12列的數組中。然后根據數據的大小進行排序,比如我繪制2002年的數據,排好序了之后的情況如圖
這是對應的使用率
0代表這個時間的數據缺失,由於網站數據的問題,會缺少某一時間的數據,這里設置了一個循環標記,用標記來匹配正則表達式匹配到的月份,如果兩個結果不相等則代表這個月數據缺失,當發現數據缺失的時候,會自動為這個月的使用率補0。
另外有看到有兩個jav,其實下面的jav是JavaScript語言,我只截取了名字的三個長度,方便清楚的看到排名情況。這里簡單的解釋一下。
主窗口的設計省略,在選擇不同的信息時會出現不同控件。
下面說繪圖,繪圖在Java的JPanel中繪圖。我們要想自由繪圖,就需要重寫JPanel類中的public void paintComponent(Graphics g)方法然后調用g.drawLine()函數,對排好序的數據進行繪制。圖形是根據他們在某一時間固定的排名進行繪制的。
四、程序運行結果
算法實現后首先來看一下運行結果,我還是繪制2002年的排名結果,以便更好對應上圖中的排名情況。橫軸是月份,豎軸是排名,看效果。
x軸以月為單位時,可以繪制2001 – 2019 年的數據,某一時刻缺少數據時,可以自動跳過。
x軸以年為單位時,可以繪制2001 – 2019 年每一年年平均使用率排名或者每一年每一個月的排名情況。
首先來看2001-2019年年平均使用率情況
這個是數組里的使用率數據。
看一下具體某個月份的排名情況
有一些數據空缺是因為某一年的3月份沒有數據,我們把排名情況的數據截圖下來,可以看到,2001、2008年這兩年3月的數據都是0,上文已經說過,0代表數據缺少。
可以看到,上圖中沒有繪制數據的的時間的使用率均為0。
五、實現保存功能
當點擊保存按鈕時可以把自己繪制的圖形保存至計算機中,首先來看核心代碼:
1 //文件選擇框,點擊確定時,返回選擇文件的路徑。 2 public static String fileSave(Component parent,String name) { 3 JFileChooser fileChooser = new JFileChooser(); 4 fileChooser.setSelectedFile(new File(name)); 5 int result = fileChooser.showSaveDialog(parent); 6 if (result == JFileChooser.APPROVE_OPTION) { 7 File file = fileChooser.getSelectedFile(); 8 return file.getAbsolutePath(); 9 } 10 else 11 return null; 12 }
這部分的是實現文件保存,但是我們需要路徑,所以用JfileChooser類來選擇路徑,選擇好路徑並且完成命名后返回路徑的字符串給上部分代碼中的file,考慮到重名問題,做了一些處理,比如我要保存名字為"hello.jpg"的文件,當文件存在時,會自動保存為"hello1.jpg"。
來看一下保存的結果。
打開它
完成。