麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

簡單的java采集程序二

2019-11-14 21:03:09
字體:
來源:轉載
供稿:網友
簡單的java采集程序二

繼【簡單的java采集程序】,這里將完成對整個網站的號碼段的采集任務。

【使用預編譯+批處理采集網頁內容至數據庫表中】

 

       在之前我們用statement類來創建sql語句的執行對象,以實現插入字段到數據庫的操作,但由于插入的數據量較大,如果繼續用statement操作話,會很耗時間,我們用其子類PReparedStatement來進行操作。

     PreparedStatement 可以實現sql語句的預編譯,我們只需要通過其setString()方法傳參即可,這樣不僅效率提高了,而且也會更加安全,可防止SQL注入。推薦相關文章

 

     另外我們還可以調用其addBatch()方法 和 executeBatch()實現批量插入處理。

代碼如下,喜歡把數據庫鏈接作為一個單獨的類

import java.sql.DriverManager;import java.sql.SQLException;import com.MySQL.jdbc.Connection;public class database {public static String driver ="com.mysql.jdbc.Driver";public static String url="jdbc:mysql://127.0.0.1:3306/tele_dat?autoReconnect=true&characterEncoding=UTF-8";public static String user   ="root";public static String passWord = "123456";public static java.sql.Connection conn = null;//返回一個數據庫連接對象public static  Connection  ConnectToDataBase(){try {Class.forName(driver);} catch (ClassNotFoundException e) {System.out.println("加載驅動失敗");e.printStackTrace();}try {conn = DriverManager.getConnection(url, user, password);System.out.println("連接成功");} catch (SQLException e) {System.out.println("連接出問題了");e.printStackTrace();}return (Connection) conn;}//測試連接數據庫public static void main(String args[]){database.ConnectToDataBase();}}

主體程序

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import java.sql.Connection;import java.sql.PreparedStatement;import java.util.regex.Matcher;import java.util.regex.Pattern;public class Crawl {private static Connection conn = database.ConnectToDataBase();      static String home_url = "http://www.hiphop8.com";   //網站首頁        static String pattern_pro_city = "<DIV class=title><SPAN>(.*?) - (.*?)<///SPAN><///DIV>";   //匹配省名,市名 static String pattern_number = ">(13//d{5}|15//d{5}|18//d{5}|147//d{4})<";  //匹配號碼段 static String pattern_pro ="//w{3}//.//w{7}//.//w{3}/////w{4}/////w+";   //省份URLstatic String pattern_city_hz="<LI><A href=/"(.*?)/" target=_blank>";    //城市URL的后綴 //編譯預處理相關選項 static String insertSQL = "insert ignore into number_segment(segment,province,city) values(?, ?, ?)";    static PreparedStatement pst = null; static int num_pro = 0;static int num_city=0;    static int all_num_tele = 0;public static void  main(String[] args) throws Exception {String PreStat =  "insert ignore into number_segment(segment,province,city) values (?,?,?) ";  pst = conn.prepareStatement(PreStat.toString()); Matcher mat_home = get(home_url,pattern_pro);long start = System.currentTimeMillis();while(mat_home.find()){num_pro++;System.out.println("------第"+num_pro+"個省-----");String city_url_qz = "http://"+mat_home.group()+"/";int len = city_url_qz.length();//這里換成StringBuffer來最字符串進行相加處理StringBuffer city_ur = new StringBuffer();city_ur.append(city_url_qz);Matcher mat_city_hz = get(city_url_qz,pattern_city_hz);while(mat_city_hz.find())                  //通過拼接獲得 城市的完整url{num_city++;System.out.println("第"+num_city+"個市");String last_city_url=city_ur.append(mat_city_hz.group(1)).toString();//String last_city_url = city_url_qz + mat_city_hz.group(1);int len2 = last_city_url.length();One_City_Tele_to_DB(last_city_url);city_ur.delete(len,len2);}}long end = System.currentTimeMillis();long time = (end-start)/(1000*60);conn.close();System.out.println("查詢到的電話號碼段總數量:"+all_num_tele);System.out.println("花費的時間是:"+time);} public  static void One_City_Tele_to_DB(String url) throws Exception    {       int this_city_num=0;    String pro = null;    String city = null;     Matcher mat_pro_city = get(url,pattern_pro_city);  //獲取省名字  市名字 while(mat_pro_city.find()) { String long_pro = mat_pro_city.group(1);     pro = long_pro.substring(0, long_pro.length()-1); String long_city = mat_pro_city.group(2);     city = long_city.substring(0, long_city.length()-10); System.out.println("省份:"+pro+"  "+"城市:"+city+"     正在插入號碼段進數據庫");  }  Matcher mat_number = get(url,pattern_number);      //獲取號碼段 while(mat_number.find()) { pst.setString(1,mat_number.group(1)); pst.setString(2, pro); pst.setString(3, city); pst.addBatch(); this_city_num++; all_num_tele++; } pst.executeBatch();  //每次批量插入一個城市的號碼段 pst.clearBatch(); System.out.println("該市插入的號碼段的數量是:"+ this_city_num);} //正則匹配public static  Matcher get(String str_url, String pattern) throws Exception {        String urlsource = get_Html(str_url);Pattern p = Pattern.compile(pattern);Matcher m = p.matcher(urlsource);return m;}//獲取網頁內容public static String get_Html(String str_url) throws IOException{    URL url = new URL(str_url);    String content="";StringBuffer page = new StringBuffer();try {BufferedReader in = new BufferedReader(new InputStreamReader(url                    .openStream()));while((content = in.readLine()) != null){page.append(content);}} catch (IOException e) {e.printStackTrace();}        return page.toString();    }}

      實際運行程序,發現有500多個重復的號碼段,因為襄樊市 改成 襄陽市,這兩個市的號碼段全部一樣,而數據庫表中是以segment(號碼)作為主鍵,所以要設置,當插入有相同主鍵的sql語句時,自動忽略跳過,方法就是在insert 后面加上ignore就可以了。

      另外設置id為auto_increment,但如果把數據表里的數據清空之后,id不會從1重新開始,這時只要在mysql命令行下輸入 truncate table table_name 就可以實現id從1開始了。

運行結果截圖image

 

     顯然,6分鐘的速度還是太慢了,后面試了幾次都是在6~8分鐘之內(不過相對于不用批處理而直接用statement已經快很多了)。因此還得想辦法優化。

【使用智能批量處理+StringBuilder的append()方法】

        在插入mysql數據庫表中時,可以以insert ignore into number_segment(segment,province,city) values(?, ?, ?),vaulues(?),values(?,?,?)…的形式進行批量插入,上面使用setString()方法傳參還是太慢了,直接用StringBuilder的append()方法吧,我們都知道appedn()方法進行字符串相加處理的效率是很高的,所以我們每次在insert語句后面加入一段“vaulues(?,?,?),”這樣形式的字符串,然后批處理插入,這里通過變量all_tele_num進行批量處理的的控制,我們規定每次批量執行2000個數據段插入。

       直接看代碼吧

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import java.sql.Connection;import java.sql.PreparedStatement;import java.util.regex.Matcher;import java.util.regex.Pattern;public class SecondCrawl {private static Connection conn = database.ConnectToDataBase();//預編譯 + StringBuilderstatic StringBuilder PreStat = new StringBuilder(); static String Qz = "insert ignore into number_segment(segment,province,city) values"; static String insertSQL = "insert ignore into number_segment(segment,province,city) values(?, ?, ?)";    static int len1 = Qz.length();    static PreparedStatement pst = null;    static String home_url = "http://www.hiphop8.com";        static String pattern_pro_city = "<DIV class=title><SPAN>(.*?) - (.*?)<///SPAN><///DIV>";   //匹配省名,市名 static String pattern_number = ">(13//d{5}|15//d{5}|18//d{5}|147//d{4})<";  //匹配號碼段 static String pattern_pro ="//w{3}//.//w{7}//.//w{3}/////w{4}/////w+";   //省份URLstatic String pattern_city_hz="<LI><A href=/"(.*?)/" target=_blank>";    //城市URL的后綴 static int num_pro = 0;static int num_city=0;static int all_num_tele=0;public static void  main(String[] args) throws Exception {Matcher mat_home = get(home_url,pattern_pro); conn.setAutoCommit(true);  PreStat.append(Qz);  pst = conn.prepareStatement(insertSQL);   //預編譯long start = System.currentTimeMillis();while(mat_home.find()){num_pro++;System.out.println("------第"+num_pro+"個省-----");String city_url_qz = "http://"+mat_home.group()+"/";int len = city_url_qz.length();StringBuffer city_ur = new StringBuffer();city_ur.append(city_url_qz);Matcher mat_city_hz = get(city_url_qz,pattern_city_hz);while(mat_city_hz.find())        //獲得城市的url{num_city++;System.out.println("第"+num_city+"個市");String city_url=city_ur.append(mat_city_hz.group(1)).toString();int len2 = city_url.length();One_City_Tele_to_DB(city_url);city_ur.delete(len,len2);}}long end = System.currentTimeMillis();long time = (end-start)/(1000*60);pst.executeBatch();   //批處理執行最后面剩余的部分conn.close();System.out.println("查詢到的電話號碼段總數量:"+all_num_tele);System.out.println("花費的時間是:"+time+"分多鐘/n"+"以微秒為單位:"+(end-start)+"微秒");}//一個城市的手機號碼段處理函數public  static void One_City_Tele_to_DB(String url) throws Exception    { String city=null; String pro =null;    int this_city_num = 0; Matcher mat_pro_city = get(url,pattern_pro_city);  while(mat_pro_city.find()) { String long_pro = mat_pro_city.group(1); pro = long_pro.substring(0, long_pro.length()-1); String long_city = mat_pro_city.group(2); city = long_city.substring(0, long_city.length()-10);  System.out.println("省份:"+pro+"  "+"城市:"+city+"     正在插入號碼段進數據庫...");  }  String temp = ",'"+pro+"','"+city+"'),"; Matcher mat_number = get(url,pattern_number); while(mat_number.find()) { PreStat.append("("+mat_number.group(1)).append(temp); this_city_num++; all_num_tele++; if(all_num_tele<=208000 && all_num_tele % 2000==0) { PreStat.deleteCharAt(PreStat.length()-1);   //除去sql語句后的逗號 pst.addBatch(PreStat.toString());  pst.executeBatch(); pst.clearBatch(); PreStat.delete(len1, PreStat.length());   //情況sql語句后面部分以釋放空間 } } if(all_num_tele>208000)             //后面不足2000部分的城市加入批處理中先不執行 { PreStat.deleteCharAt(PreStat.length()-1); pst.addBatch(PreStat.toString()); PreStat.delete(len1, PreStat.length()); } System.out.println("該市插入的號碼段的數量是:"+ this_city_num);} //正則匹配public static  Matcher get(String str_url, String pattern) throws Exception {       String urlsource = get_Html(str_url);Pattern p = Pattern.compile(pattern);Matcher m = p.matcher(urlsource);return m;}//獲取網頁內容public static String get_Html(String str_url) throws IOException{   URL url = new URL(str_url);   String content="";StringBuffer page = new StringBuffer();try {BufferedReader in = new BufferedReader(new InputStreamReader(url                   .openStream()));while((content = in.readLine()) != null){page.append(content);}} catch (IOException e) {e.printStackTrace();}       return page.toString();   }}

運行截圖030641D5CD414D92B15219D95CAFC302

 

        測試了幾次,運行時間是在2分鐘左右,又提速了不少,不過還是有很大的提升空間的,因為自己在測試時,如果程序僅僅是插入20多萬的sql語句,可以在幾秒鐘內完成。

      說道再優化,自己的思路是把網站url采集和插入數據庫使用多線程進行并發操作,現在正在學習java的多線程,也在嘗試用多線程的方法寫采集程序,如果大家還有更好的方法,也可以給我留言,愿意和大家一起交流進步。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黄色特级毛片 | 成人精品aaaa网站 | 久久草草影视免费网 | 性生活视频一级 | av观看网站 | 日韩色视频 | 九九午夜| 一区二区三区黄色 | 久久99国产精品免费网站 | 黄污网站在线观看 | 国产亚洲精品久久777777 | 色偷偷一区 | 草逼一区 | 福利在线免费视频 | xxxx69hd一hd| 在线视频观看成人 | 国产一区二精品区在线 | 亚洲精品 在线播放 | 美国av在线免费观看 | 多人乱大交xxxxx变态 | 91网站链接| 日韩精品中文字幕在线播放 | 黄色aaa视频 | 成年人激情在线 | 免费黄色在线电影 | 欧美国产成人在线 | 久久久久久久久久久影视 | 一级黄色片武则天 | 369看片你懂的小视频在线观看 | 韩国草草影院 | 污片视频网站 | 久久久精品视 | 粉嫩粉嫩一区二区三区在线播放 | 欧美a在线看 | v片在线看 | 欧美 日韩 亚洲 中文 | 国产精品99爱 | 国产高潮失禁喷水爽到抽搐视频 | h色网站免费观看 | 免费网址黄 | 欧美精品日日鲁夜夜添 |