用JAVA實現簡單爬蟲多執行緒抓取
阿新 • • 發佈:2018-12-31
在迴圈爬取得基礎上進行多執行緒爬蟲,本程式中使用的三個執行緒,執行緒為實現runnable介面,並使用物件鎖防止併發共同去訪問同一個物件。讓三個執行緒同時爬去同一個url並且得到的新的url不重複。
import java.io.*;
import java.net.*;
public class WebCrawler{
public static void main(String[] args){
runcrawler t1=new runcrawler();
runcrawler t2=new runcrawler();
runcrawler t3=new runcrawler();
t1.start();
t2.start();
t3.start();
}
}
class runcrawler extends Thread{
String s1="<a href=\"http://";
String url="http://www.sina.com";
static int i=0;
static String [] urlconntion=new String[100];
public void run() {
newCrawler cr=new newCrawler(url,s1,urlconntion);
String s2=cr.find();
while(urlconntion[90]==null){
//執行緒鎖,防止併發導致的執行緒安全
synchronized(this)
{
if(s2==null){
cr=new newCrawler(url,s1,urlconntion);
s2=cr.find();
}
System.out .println(s2);
cr=new newCrawler(s2, s1,urlconntion);
urlconntion[i++]=s2;
s2=cr.find();
}
}
}
}
class newCrawler {
String url=null;
String prefix=null;
//爬去過的url地址集合
String[] urlconntion=null;
//爬蟲類的建構函式
newCrawler(String url,String prefix,String[] urlconntion){
this.url=url;
this.prefix=prefix;
this.urlconntion=urlconntion;
}
//根據類的url開始爬取新的url實現迴圈爬取
public String find(){
URL u=null;
URLConnection con=null;
BufferedReader bfr=null;
String rpurl=null;
try {
u=new URL(url);
con=u.openConnection();
//模擬成使用者,訪問部分網站,部分網站會拒絕爬蟲爬取
con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
InputStream is=con.getInputStream();
bfr=new BufferedReader(new InputStreamReader(is));
String s;
while((s=bfr.readLine())!=null){
if(s.indexOf(prefix)>=0)
{
rpurl=getUrl(s);
if(urlrepetition(rpurl)!=-1){
return rpurl;
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
bfr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
//判斷url是否被爬去過,如果被爬去可返回-1,如果沒有則返回1
public int urlrepetition(String rpurl){
int i=0;
while(urlconntion[i]!=null){
if(urlconntion[i++].equals(rpurl)){
return -1;
}
}
return 1;
}
//從爬去過的原始碼中擷取url地址;
public String getUrl(String s){
int index1=s.indexOf(prefix);
s=s.substring(index1+9);
int index2=s.indexOf("\"");
s=s.substring(0,index2);
return s;
}
}
執行結果:
- 總結:
1.自己剛剛接觸爬蟲,感覺這程式雖然實現了,但是在效率上不是特別高,自己嵌套了三個迴圈以上,這樣在時間和空間上耗費比較多。
2.上一個寫的迴圈爬去的問題還是沒解決。