2015-11-26 56 views
0

我正在研究一個Web爬蟲,我試圖建立的功能的一部分是它解析頁面時,並刪除重複的鏈接時拉鍊接。刪除函數列表迭代器似乎並沒有刪除項目

import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.ListIterator;  
import com.bal.Link; 
import com.bal.WebPage; 

public class webCrawlerMain { 

    public static void main(String[] args) {    
     WebPage wp = null; 
     int numberOfLoopsThroughLinks = 22; 
     ArrayList<Link> links = new ArrayList<>(); 
     links.add(new Link("http://jsoup.org/")); 
     ArrayList<Link> foundLinks; 
     try{ 
      for(int i=0; i < numberOfLoopsThroughLinks; i++){ 

       for(ListIterator<Link> ls = links.listIterator(); ls.hasNext();){//need to use an iterator to avoid a concurrent modification exception 
        Link l = ls.next(); 
        if(!l.isVisited()){//if link hasn't been visited 
         l.setVisited(true); 
         System.out.println("Parsing the following URL:"+l.getUrl()); 
         wp=new WebPage(l.getUrl()); 
         wp.parsePage(); 
         foundLinks = wp.getLinks(); 
         ArrayList<Link> newLinks = wp.getLinks(); 
         newLinks=addToLinks(links, newLinks); 
         for(Link nL: newLinks){       
          ls.add(nL);       
         }             
        }      
       }  
      }    

     }catch(Exception e){ 
      System.out.println("Web page url in use at time of exception "+ wp.getUrl()); 
      e.printStackTrace(); 
     } 



    } 

    public static ArrayList<Link> addToLinks(ArrayList<Link> links, ArrayList<Link> newLinks){ 


     for(ListIterator<Link> iterator = newLinks.listIterator(); iterator.hasNext();){ 
      Link nL = iterator.next(); 

      for(Link l: links){ 
       if(nL.getUrl().equals(l.getUrl())){ 
        //System.out.println(nL.getUrl()+" == "+l.getUrl()); 
        //System.out.println("removed a duplicate link"); 
        iterator.remove(); 
        if(iterator.hasNext()){ 
         iterator.next(); 
        } else { 
         break; 
        } 

       } 
      } 
     } 
     return newLinks; 


    } 

} 

我遇到的問題是我得到重複打印的解析。而且,由於我刪除了要添加的AL中的重複項,並且只從一個鏈接開始,所以我不應該添加重複項。如果它們是相同的元素,它們應該被標記爲已訪問,因此不應該再次訪問。

*似乎大多數重複鏈接以#結尾。如果我調試,我可以看到#和一些鏈接,然後一些額外的東西,即http://unicodelookup.com#thai 但這些似乎並沒有出現。但是,如果我添加一個作爲該初始鏈接的第一個URL,它將顯示。用Java中的#和字符串有沒有什麼奇怪的東西,不會影響字符串文字作爲參數?

**所以我擺脫了與#(顯然Jsoups解析器滴他們之後的東西,因爲他們表示在頁面上的地方,而不是一個獨特的href)。仍然有重複的問題。

+0

我認爲你需要閱讀。 http://stackoverflow.com/help/mcve –

+0

假設你的'Link'類已經覆蓋了'equals'和'hashcode'方法,你可以簡單地使用'links.removeAll(newLinks)' – MadProgrammer

+0

爲什麼不使用Set而不是數組列表?你將不會有重複。 –

回答

0

addToLinks函數移動指針兩次,第二個移動元素有可能被複制。

首先 - 移動

Link nL = iterator.next(); 

發送移動

if(iterator.hasNext()){ 
        iterator.next(); 
       } else { 
        break; 
       } 
+0

謝謝。我沒有使用迭代器。 – Malcire

+0

似乎我需要第二步,如果我刪除 如果(iterator.hasNext()){iterator.next();其他{ 中斷; } 我得到一個非法的狀態異常 – Malcire

+0

看起來我需要在該代碼片段中使用hasPrevious()和previous()。 – Malcire