緣起於玩唱吧,因爲唱吧好友少,訪問量低,又不想加什麼親友團之類的,主要是太麻煩了,因而我就琢磨唱吧的訪問機制,準備用java的httpclient庫來進行刷訪問量,想到動態IP反覆使用就想到了用多線程來進行刷,但發現速度並無增快,仍然是刷完一個網址刷下一個網址,這裏刷的順序是隨機的。 主要讓人傷腦筋的是那代理IP,去網上找了1000多個IP,有好多都是響應速度太慢了,以致於我設定了超時機制,超過一段時間的話就拋出異常並且忽略,僅僅是速度太慢了,有待提快速度!!誰有好的改進的建議歡迎你們來分享,求你們指點。html
注:如下的是第一次寫的刷訪問量代碼的初版,後來想一想代碼有問題,因爲在實際測試中發現儘管用了線程,但是沒有真正起到多線程的做用,效率沒有獲得提高,因爲問題也算是學習的重要途徑,因此我初版代碼就不改了,給你們做爲借鑑。在再後面貼上改進版本號的多線程刷訪問量代碼,這個代碼通過測試後發現速度明顯獲得提高!結果然實有效!java
如下列出如下初版代碼的缺陷的緣由:web
主要就是因爲一開始我對多線程編程中的start和run的方法的模糊認識致使的,首先來談談什麼是二者的差異:apache
(1)start:編程
用start方法來啓動線程,真正實現了多線程的運行,這是無需等待run方法代碼運行完成就可以直接繼續運行如下的代碼。經過調用Thread類的start方法來啓動一個線程,這是此線程就處於就緒狀態,並無運行,一旦獲得了cpu的時間片,就開始運行run方法,這裏的run成爲線程體,它包括了要運行的這個線程的內容,run方法運行結束,此線程就終止。瀏覽器
(2)run:cookie
run方法僅僅是類的一個普通方法而已,假設直接調用run方法,程序中依舊僅僅有主線程這一個線程,其程序運行路徑仍是僅僅有一條,仍是要順序運行,仍是要等待run方法運行完成後才幹夠繼續運行小面的代碼,這樣就沒有達到寫線程的目的了。多線程
所以,在第一個版本號的代碼中個人線程的啓動方法是run,因此沒有其它線程產生,因此沒有達到多線程的目的。app
web_look.java學習
import java.io.*; import java.util.*; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.HttpConnectionParams; public class Web_look { public static void main(String[] args) throws IOException { int count=0; Map<String,String> map =new HashMap<String,String>(); FileReader reader=new FileReader("c://IP.txt");//讀代替理IP地址 BufferedReader br=new BufferedReader(reader); String str=null; while((str=br.readLine())!=null)//格式寫成IP+端口 { String result[]=str.split("@"); String info[]=result[0].split(":"); map.put(info[0], info[1]); } Set<String> set=map.keySet(); Iterator<String> iter=set.iterator(); HttpClient client = new HttpClient(); //設置超時時間 client.setTimeout(10000); client.setConnectionTimeout(10000); //設置cookie管理策略 client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY); while(iter.hasNext())//不斷的取出IP和端口 { String key=iter.next(); System.out.println(key+":"+map.get(key)); //用try-catch來忽略超時異常繼續運行 try{ //設置代理server地址和端口 client.getHostConfiguration().setProxy(key,Integer.parseInt(map.get(key))); //這是用刷的是唱吧的訪問量,親測有效,僅僅只是效率不是怎麼高,因爲代理server有快有慢,因此設置了超時機制。 //而且,貌似一個IP不能連續刷多首歌曲,因此就僅僅能附帶刷刷別的網頁好了。 MyThread song1= new MyThread("http://changba.com/s/TKSPrlyJgkd4cUir8pGZkQ?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); MyThread song2= new MyThread("http://changba.com/s/48SlsCcpHNiNXPji_VyU5Q?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); // MyThread song3= new MyThread("http://changba.com/s/0GP_YQzqRJOJUHjDbRpPBg?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); // MyThread song4= new MyThread("http://changba.com/s/XXCW9aOqzkiQW1ha1hSMvg?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); // MyThread song5= new MyThread("http://changba.com/s/7HpyApA4gWXoh-V0usAMfw?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); // MyThread song6= new MyThread("http://changba.com/s/8y6IvXu-8uwUrrT7uEtHEA?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); // MyThread song7= new MyThread("http://changba.com/s/lyBc498kdr9N4DgR5lqFCg?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk",client); song1.run(); song2.run(); // song3.run(); // song4.run(); // song5.run(); // song6.run(); // song7.run(); //使用GET方法,假設server需要經過HTTPS鏈接,那僅僅需要將如下URL中的http換成https //使用POST方法 //HttpMethod method = new PostMethod("http://changba.com/s/0yKWymXZXeGZcF0P3mM8Bg?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk"); //設置請求頭,來模擬瀏覽器登錄,有些站點需要,有些站點不需要,看詳細是什麼站點了 // method.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;"); // method.setRequestHeader("Accept-Language", "zh-cn"); // method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3"); // method.setRequestHeader("Accept-Charset","encoding"); // method.setRequestHeader("Keep-Alive", "300"); // method.setRequestHeader("Connection", "Keep-Alive"); // method.setRequestHeader("Cache-Control", "no-cache"); //client.executeMethod(method); //打印server返回的狀態 //System.out.println(method.getStatusLine()); //打印返回的信息 //System.out.println(method.getResponseBodyAsString()); //釋放鏈接,不然會報錯recycle //method.releaseConnection(); }catch(Exception e) { e.printStackTrace(); } count++; System.out.println("第"+count+"個IP地址"); } } }
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.PostMethod; public class MyThread extends Thread{ private String web_name; private HttpClient client; public MyThread(String web_name,HttpClient client) { this.web_name=web_name; this.client=client; } public void run() { HttpMethod method = new PostMethod(web_name); try { client.executeMethod(method); System.out.println(method.getStatusLine()); System.out.println(method.getResponseBodyAsString()); method.releaseConnection(); }catch(Exception e) { e.printStackTrace(); } } }
這裏的多線程沒有起到預期的效果,因爲貌似唱吧裏面對同一個IP訪問多個歌曲僅僅算訪問的第一首,因此哪怕寫了再多線程也僅僅算訪問了第一首,第一首歌訪問量加了1,其它的仍然不變。因此,假設有其它頁面的話可以附帶將其它頁面增長多線程來刷。
——————————————————————————————————————————————————— 切割線———————————————————————————————————————————————————
如下我就貼上個人改進版,這個版本號真正實現了多線程訪問,而且更加具備靈活性,可以多個線程刷一樣或者不一樣的網頁,而且可以選擇不一樣的IP地址文件。
web_look.java
import java.io.*; import java.util.*; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.HttpConnectionParams; public class Web_look { public static void main(String[] args) throws IOException { String web_name=null; web_name="http://changba.com/s/0yKWymXZXeGZcF0P3mM8Bg?code=Gt1bjDM0qnHCJdoHUPnwOOfDhUzYnTz-KfffnVr9zf7j8kkd7OlN9bo9NlHq5j6rFeHPZ8iGR3663XuAiDYOEcYV2ky5V8Bk"; //用try-catch來忽略超時異常繼續運行 try{ Thread threads[]=new Thread[5]; threads[0]= new Thread(new MyThread(web_name,"c://IP.txt")); threads[1]= new Thread(new MyThread(web_name,"c://IP1.txt")); threads[2]= new Thread(new MyThread(web_name,"c://IP2.txt")); threads[3]= new Thread(new MyThread(web_name,"c://IP3.txt")); threads[4]= new Thread(new MyThread(web_name,"c://IP4.txt")); for(int i=0;i<5;i++) { threads[i].start(); } }catch(Exception e) { e.printStackTrace(); } } }
MyThread.java
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.PostMethod; public class MyThread implements Runnable{ private String web_name; private String IP_file; private HttpClient client = new HttpClient(); private String str=null; private FileReader reader; private BufferedReader br; private Map<String,String> map =new HashMap<String,String>(); public MyThread(String web_name,String IP_file) { this.web_name=web_name; this.IP_file=IP_file; } public void run() { try { reader=new FileReader(IP_file); br=new BufferedReader(reader); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }//讀代替理IP地址 try { while((str=br.readLine())!=null)//格式寫成IP+端口 { String result[]=str.split("@"); String info[]=result[0].split(":"); map.put(info[0], info[1]); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Set<String> set=map.keySet(); Iterator<String> iter=set.iterator(); //設置超時時間 client.setTimeout(10000); client.setConnectionTimeout(10000); //設置cookie管理策略 client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY); while(iter.hasNext())//不斷的取出IP和端口 { String key=iter.next(); System.out.println(key+":"+map.get(key)); try { //設置代理server地址和端口 client.getHostConfiguration().setProxy(key,Integer.parseInt(map.get(key))); //這是用刷的是唱吧的訪問量,親測有效,僅僅只是效率不是怎麼高,因爲代理server有快有慢,因此設置了超時機制。 //而且,貌似一個IP不能連續刷多首歌曲,因此就僅僅能附帶刷刷別的網頁好了。 }catch(Exception e) { e.printStackTrace(); } HttpMethod method = new PostMethod(web_name); try { System.out.println(IP_file); client.executeMethod(method); //System.out.println(method.getStatusLine()); //System.out.println(method.getResponseBodyAsString()); method.releaseConnection(); }catch(Exception e) { e.printStackTrace(); } } } }