亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

簡單的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的多線程,也在嘗試用多線程的方法寫采集程序,如果大家還有更好的方法,也可以給我留言,愿意和大家一起交流進步。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91av在线免费观看| 久久久中文字幕| 国产日产亚洲精品| 日韩中文字幕在线观看| 日韩av在线导航| 亚洲天堂男人天堂| 成人久久久久爱| 国产在线视频欧美| 久久综合88中文色鬼| 91在线色戒在线| 久久久精品网站| 国产剧情久久久久久| 日韩欧美一区二区在线| 国产福利精品在线| 国产精品羞羞答答| 欧美精品第一页在线播放| 亚洲人成电影网站色xx| 久久久在线视频| 日韩电影免费观看中文字幕| 91网站免费看| 视频直播国产精品| 日韩中文理论片| 一道本无吗dⅴd在线播放一区| 亚洲在线观看视频| 中文字幕免费精品一区高清| 国产精品成人一区二区三区吃奶| 亚洲九九九在线观看| 日韩小视频在线| 91久久久久久久久久| 中文字幕av一区中文字幕天堂| 欧美性xxxxx极品娇小| 欧美性极品xxxx做受| 亚洲精品美女视频| 精品国产一区二区三区久久| 亚洲欧美国产va在线影院| 粗暴蹂躏中文一区二区三区| 久久久久久国产精品三级玉女聊斋| 深夜成人在线观看| 欧美国产日韩视频| 91在线色戒在线| 九九久久综合网站| 国产精品久久久久999| 国产在线98福利播放视频| 一区二区亚洲精品国产| 欧美性受xxxx白人性爽| 日韩欧亚中文在线| 午夜欧美大片免费观看| 日韩精品丝袜在线| 亚洲第一中文字幕| 国产欧美va欧美va香蕉在| 欧美有码在线观看| 日韩成人免费视频| 国产一区二区黑人欧美xxxx| 91精品国产综合久久久久久蜜臀| 欧美午夜久久久| 欧美性猛交99久久久久99按摩| 国产69精品久久久久9999| 欧美视频在线观看免费| 91中文字幕一区| 欧美极度另类性三渗透| 日韩美女主播视频| 欧美日韩在线视频一区二区| 久热在线中文字幕色999舞| 成人免费午夜电影| 国产精品夫妻激情| 欧美成年人视频网站欧美| 欧美视频在线视频| 久久久在线视频| 国产一区二区免费| 国产一区二区三区久久精品| 久久精品亚洲精品| 日韩在线免费av| 97精品一区二区视频在线观看| 中文字幕亚洲字幕| 亚洲国产高清福利视频| 国产精品永久免费视频| 欧美床上激情在线观看| 亚洲美女av网站| 亚洲午夜小视频| 成人中文字幕在线观看| 日本不卡视频在线播放| 亚洲国产精品一区二区久| 色婷婷久久一区二区| 日韩精品在线免费播放| 国产精品第一页在线| 国产免费久久av| 中文字幕在线视频日韩| 亚洲激情在线观看视频免费| 伊人久久综合97精品| 亚洲成人av中文字幕| 日韩免费中文字幕| 久久夜精品va视频免费观看| 日韩精品视频免费| 精品国产91乱高清在线观看| 亚洲一区二区三区乱码aⅴ| 久久国产精品久久久久| 国内精品美女av在线播放| 色婷婷综合成人av| 欧美精品videosex性欧美| 国产精品扒开腿做爽爽爽的视频| 欧美成年人在线观看| 精品久久久视频| 欧美日韩亚洲一区二区三区| 国产视频在线一区二区| 亚洲综合在线小说| 欧美在线观看网站| 色一情一乱一区二区| 精品夜色国产国偷在线| 日韩视频在线免费观看| 久久精品国产精品亚洲| 欧美性色19p| 2025国产精品视频| 亚洲最大激情中文字幕| 俺去亚洲欧洲欧美日韩| 国产区精品视频| 日韩亚洲欧美中文在线| 国产亚洲a∨片在线观看| 国产欧美 在线欧美| 精品国产一区二区三区四区在线观看| 欧美成人一区在线| 亚洲日本中文字幕免费在线不卡| 欧美精品激情blacked18| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲毛片在线看| 欧美二区乱c黑人| 91精品国产乱码久久久久久蜜臀| 欧美最猛性xxxx| 国产网站欧美日韩免费精品在线观看| 亚洲图中文字幕| 欧美中文在线观看国产| 欧美性猛交xxx| 欧美大片欧美激情性色a∨久久| 国产97在线播放| 亚洲国产欧美一区二区丝袜黑人| 中文字幕日韩在线播放| 久久这里只有精品99| 日韩中文字幕精品| 亚洲成人激情视频| 亚洲成人av资源网| 欧美日韩美女在线| 亚洲福利视频网| 亚洲色无码播放| 日韩欧美在线字幕| 亚洲va欧美va在线观看| 国产日韩欧美中文在线播放| 国产剧情日韩欧美| 不卡伊人av在线播放| 欧美日韩国产二区| 日韩一区二区av| 海角国产乱辈乱精品视频| 日韩欧美aⅴ综合网站发布| 国产精品第三页| 亚洲欧美日韩国产精品| 91av在线国产| 国产一区二区三区在线观看网站| 26uuu另类亚洲欧美日本老年| 激情久久av一区av二区av三区| 日韩av片免费在线观看| 国产成人av在线| 国产精品视频在线播放| 欧美大片va欧美在线播放| 91精品久久久久久| 精品久久久久久亚洲国产300| 久久九九精品99国产精品|