Java 制作蜘蛛爬行网站

Java 制作蜘蛛爬行网站,java,web,webpage,Java,Web,Webpage,我试图创建一个java类,用于获取特定页面的单词和链接。假设页面是stackoverflow.com。我希望类首先检查并存储该页面上的所有链接。在它存储并检查了该页面上的所有链接后,我希望它分支到第一页中的每个页面,然后再次检查所有链接,直到它完全分支并检查了所有链接。我只设法将它扩展到第二组链接。代码如下: public void spiderLeg(String webAdress){ public HashSet < String > getLink = new Has

我试图创建一个java类,用于获取特定页面的单词和链接。假设页面是stackoverflow.com。我希望类首先检查并存储该页面上的所有链接。在它存储并检查了该页面上的所有链接后,我希望它分支到第一页中的每个页面,然后再次检查所有链接,直到它完全分支并检查了所有链接。我只设法将它扩展到第二组链接。代码如下:

  public void spiderLeg(String webAdress){
  public HashSet < String > getLink = new HashSet <String>();
    a = new Reader(webAdress);
    a.run();
    System.out.println("CRAWLING");
    for(String s : a.getLinks()){
        getLink.add(s);
        a = new Reader(s);
        a.run();

        for(String v : a.getLinks()){
            getLink.add(v);
            a = new Reader(v);
            a.run();
        }
        for(String h : l.getLinks()){
            getLink.add(h);
        }

    }


}
public void spiderLeg(字符串webaddress){
公共HashSetgetLink=newhashset();
a=新阅读器(网址);
a、 run();
System.out.println(“爬行”);
for(字符串s:a.getLinks()){
getLink.add;
a=新读取器;
a、 run();
for(字符串v:a.getLinks()){
getLink.add(v);
a=新读取器(v);
a、 run();
}
for(字符串h:l.getLinks()){
getLink.add(h);
}
}
}

正如你所看到的,我只能让它分支到第二组链接。我希望它分支,直到不再有任何尚未访问的链接。我只是不知道如何才能做到这一点。

您所描述的是递归操作,而不是循环操作

如果
s
是一个与最初传递给该方法的地址相同的地址,则使用
s
递归调用该方法。大概是这样的:

public void spiderLeg(String webAdress){
    public HashSet < String > getLink = new HashSet <String>();
    a = new Reader(webAdress);
    a.run();
    System.out.println("CRAWLING");
    for(String s : a.getLinks()){
        getLink.add(s);
        a = new WebPageReader(s);
        a.run();

        spiderLeg(s); // <-- here
    }
}
private HashSet < String > getLink = new HashSet <String>();

public void spiderLeg(String webAdress, int depth){

    // check against a "max depth constant"
    if (depth > 10){
        return;
    }

    a = new Reader(webAdress);
    a.run();
    System.out.println("CRAWLING");
    for(String s : a.getLinks()){
        getLink.add(s);
        a = new WebPageReader(s);
        a.run();

        spiderLeg(s, depth + 1); // increment the depth
    }
}

编辑:看起来您的
getLink
变量也需要移动到更高的范围。这是因为对该方法的每个递归调用都将有它自己的变量副本,因此每个调用在该
HashSet
中只有一个元素。相反,让它成为类级别的成员。大概是这样的:

public void spiderLeg(String webAdress){
    public HashSet < String > getLink = new HashSet <String>();
    a = new Reader(webAdress);
    a.run();
    System.out.println("CRAWLING");
    for(String s : a.getLinks()){
        getLink.add(s);
        a = new WebPageReader(s);
        a.run();

        spiderLeg(s); // <-- here
    }
}
private HashSet < String > getLink = new HashSet <String>();

public void spiderLeg(String webAdress, int depth){

    // check against a "max depth constant"
    if (depth > 10){
        return;
    }

    a = new Reader(webAdress);
    a.run();
    System.out.println("CRAWLING");
    for(String s : a.getLinks()){
        getLink.add(s);
        a = new WebPageReader(s);
        a.run();

        spiderLeg(s, depth + 1); // increment the depth
    }
}

我尝试了代码,每次调用spiderLeg时只添加一个页面。原因可能是什么?@DanZoe:定义“添加”。方法调用是递归的吗?请注意,您可能需要将一些值拉入更高的范围。例如,
getLink
只包含该方法调用的一个链接。如果希望它收集所有链接,它必须是类级成员,或者作为引用参数传递给递归方法调用。我希望getLink哈希集包含所有正在收集的链接。@DanZoe:最简单的方法可能是将该变量设为类级成员。我已经更新了答案来描述这一点。它不必是递归的,如果我理解正确,你建议进行深度优先搜索,但你也可以做广度优先,并消除每个级别的重复。无论如何,您必须做什么,否则您将在循环中运行,例如使用散列。