2014-05-03 26 views
0

我最近編寫了一個小爬蟲,用來搜索任何頁面上的鏈接,並寫入一個文件。我在集合(HashSet)中添加了代碼以避免相同的鏈接...從Set(Crawler,Jsoup,Java)寫一個文件

但由於某種原因代碼不起作用,而且我看到很多重複的文件。

你能幫助修復它中的錯誤嗎?

這裏是履帶式的代碼:

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.HashSet; 
import java.util.Set; 

import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 
import org.jsoup.select.Elements; 

public class Crawler { 

    public static void main(String[] args) { 
     Set<String> setUrlBase = new HashSet<String>(); 
     Document doc; 
     String BaseUrlTxtT = "C://Search/urlw.txt"; 
     try { 
      doc = Jsoup.connect("http://stackoverflow.com/").get(); 

      Elements links = doc.select("a[href]"); 
      for (Element link : links) { 
       String UrlLinkHref = link.attr("href"); 
       if (UrlLinkHref.indexOf("http://") == 0) { 
        setUrlBase.add(UrlLinkHref); 
        for (String strUrlHash : setUrlBase) { 
         writeToBase(BaseUrlTxtT, strUrlHash + "\n"); 
        } 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private static void writeToBase(String fileName, String text) { 
     File file = new File(fileName); 
     try { 
      if (!file.exists()) { 
       file.createNewFile(); 
      } 
      FileWriter wr = new FileWriter(file.getAbsoluteFile(), true); 

      try { 
       wr.write(text + "\n"); 
      } finally { 
       wr.close(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

回答

0

看來,在代碼

String UrlLinkHref = link.attr("href"); 
if (UrlLinkHref.indexOf("http://") == 0) { 
    setUrlBase.add(UrlLinkHref); 
    for (String strUrlHash : setUrlBase) { 
     writeToBase(BaseUrlTxtT, strUrlHash + "\n"); 
    } 
} 

要添加鏈接來設置和附加到文件集的全部內容。我所說的附加,而不是重寫,因爲你正在使用

FileWriter wr = new FileWriter(file.getAbsoluteFile(), true); 

其中true的意思是「不要刪除我的文件,但現有的後面添加新內容」,這樣你的文件可能看起來像

link1 //part written when added first link 
link1 //part written when added second link 
link2 
link1 //part written when added third link 
likn2 
link3 

(實際上,因爲HashSet的,在每個部分無序的元素可以寫成link2, link3, link1代替link1, link2, link3但你應該明白我的意思)

爲了避免它只是使用類似的代碼

String UrlLinkHref = link.attr("href"); 
if (UrlLinkHref.indexOf("http://") == 0) { 
    if (setUrlBase.add(UrlLinkHref)){//will return true if link wasn't in set yet 
     writeToBase(BaseUrlTxtT, UrlLinkHref + "\n");// so we also want to write 
                // it to file 
    } 
} 

其可以更加使用短路和(&&

String UrlLinkHref = link.attr("href"); 
if (UrlLinkHref.startsWith("http://") && setUrlBase.add(UrlLinkHref)){ 
    writeToBase(BaseUrlTxtT, UrlLinkHref + "\n");// so we also want to write 
} 

很少更多的改進

  • 要檢查是否字符串"http://"啓動被縮短不使用「神祕」的代碼,如UrlLinkHref.indexOf("http://") == 0,但只是UrlLinkHref.startsWith("http://")
  • 請勿硬編碼行分隔線\n,因爲不同的操作系統可以使用不同的行分隔符集(Windows例如使用\r\n)。取而代之的是從System.lineSeparator()。或者甚至更好,包裝你的作家在PrintWriter其中有println方法(就像System.out.println()),這將爲您添加基於OS的行分隔符。
+0

謝謝!你能幫助另一個問題,我認爲每個引用文件是一個新行,但事實證明,在同一行上的幾個鏈接,我想看到一個鏈接到一行.. – user3384347

+0

@ user3384347檢查我的最後編輯,尤其是關於行分隔符的點。 – Pshemo

+0

謝謝你超級!)) – user3384347