我正在使用网络抓取工具,我尝试构建的部分功能是在解析网页时删除链接并删除重复链接。
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 :(得分:0)
addToLinks函数正在移动指针两次,并且第二个移动元素可能是重复的。
首先 - 移动
Link nL = iterator.next();
发送移动
if(iterator.hasNext()){
iterator.next();
} else {
break;
}