我正在研究一個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)。仍然有重複的問題。
我認爲你需要閱讀。 http://stackoverflow.com/help/mcve –
假設你的'Link'類已經覆蓋了'equals'和'hashcode'方法,你可以簡單地使用'links.removeAll(newLinks)' – MadProgrammer
爲什麼不使用Set而不是數組列表?你將不會有重複。 –