Java 第一次通过后是否继续进行深度优先搜索?

Java 第一次通过后是否继续进行深度优先搜索?,java,depth-first-search,Java,Depth First Search,我正在尝试创建一个基本的基于深度优先搜索的网络爬虫。这是我目前的代码: import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.io.*; import java.net.*; public class DepthFirstSpider { private List<String> visitedList; //web pages alre

我正在尝试创建一个基本的基于深度优先搜索的网络爬虫。这是我目前的代码:

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.*;
import java.net.*;

public class DepthFirstSpider {
    private List<String> visitedList; //web pages already visited
    private static String hrefExpr = "href\\s*=\\s*\"([^\"]+)\"";
    private static Pattern pattern = Pattern.compile(hrefExpr);
    private int limit;
    private static Matcher matcher;
    private static URL contextURL;
    private static URL url;

    public List<String>  getVisitedList() { return visitedList; }

    //initialize the visitedlist and limit instance variables. Visit the starting url.
    public DepthFirstSpider(int limit, String startingURL) {
        visitedList = new ArrayList<String>();
        this.limit = limit;
        try {
            contextURL = new URL(startingURL);
        } catch (MalformedURLException e) {

        }

        visit(startingURL);
    }

    //print and add urlString to list of visited web pages 
    //create url and connect, read through html contents:
    //when href encountered create new url relative to the current url and visit it (if not already visited and limit not reached)
    public void visit(String urlString) {
        try{
            url = new URL(contextURL, urlString);
            URLConnection connection = url.openConnection();
            InputStream inputStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(inputStream));
            String nextLine;
            while((nextLine=reader.readLine()) != null){
                matcher = pattern.matcher(nextLine);
                while(matcher.find() && limit > 0 && !visitedList.contains(url.toString())){
                    System.out.println("visiting " + url.toString());
                    visitedList.add(url.toString());
                    visit(matcher.group(1));
                    limit--;
                }
            }
        } catch (MalformedURLException e){

        } catch (IOException e){

        }
    }
import java.util.*;
导入java.util.regex.Matcher;
导入java.util.regex.Pattern;
导入java.io.*;
导入java.net。*;
公共类深度优先蜘蛛{
私有列表已访问列表;//已访问的网页
私有静态字符串hrefExpr=“href\\s*=\\s*\”([^\“]+)\”;
私有静态模式=Pattern.compile(hrefExpr);
私有整数限制;
私有静态匹配器;
私有静态URL上下文;
私有静态URL;
public List getVisitedList(){return visitedList;}
//初始化visitedlist和limit实例变量。访问起始url。
public DepthFirstSpider(整数限制,字符串起始URL){
visitedList=新建ArrayList();
这个极限=极限;
试一试{
contextURL=新URL(起始URL);
}捕获(格式错误){
}
访问(启动URL);
}
//打印URL字符串并将其添加到已访问网页列表中
//创建url并连接,通读html内容:
//当href遇到相对于当前url创建新url并访问它时(如果尚未访问且未达到限制)
公共无效访问(字符串urlString){
试一试{
url=新url(上下文,url字符串);
URLConnection=url.openConnection();
InputStream InputStream=connection.getInputStream();
BufferedReader reader=新的BufferedReader(
新的InputStreamReader(inputStream));
字符串下一行;
而((nextLine=reader.readLine())!=null){
matcher=pattern.matcher(nextLine);
而(matcher.find()&&limit>0&&!visitedList.contains(url.toString())){
System.out.println(“访问”+url.toString());
添加(url.toString());
访问(matcher.group(1));
限制--;
}
}
}捕获(格式错误){
}捕获(IOE异常){
}
}
}


搜索目前没有任何问题。我需要帮助使其返回,然后转到它丢失的页面。感谢帮助。

当我做爬虫程序时,我使用了两个队列,而不是一个列表。一个队列包含要访问的URL,另一个包含已访问的URL。我添加了所有要访问的URL当我访问这些URL时,我将它们从ToVisite队列中删除(并添加到已访问队列中),并将该页面上的所有链接添加到ToVisite队列中,除非它们位于已访问队列中。这样做不需要遍历。

我可能遗漏了一些内容,但是

首先,您还需要跟踪扩展的节点。您应该将每个生成的子节点添加到堆栈(FILO)中

您应该将()每个展开的节点推送到堆栈中,并在每次迭代时弹出()。当达到限制时,您将弹出较高的节点

这是家庭作业吗


你可以在维基百科的伪代码中找到一个好的解释。

我有一个广度优先的爬虫程序可以做到这一点。但是我希望在这里使用这种特殊的搜索方法。所以你可以使用堆栈而不是队列来访问。在尽可能深入之后,你会想去下一个最深的兄弟。这有意义吗?我会想象一下如果遇到HREF,您仍然希望添加HREF,因为这比遍历部分页面然后稍后遍历其余页面更容易。这很有意义,您能举个例子吗?我还希望保持visit方法的递归性质。现在的方式是,一旦进入嵌套的while循环,while(matcher.find()&&limit>0&&!visitedList.contains(url.toString()))url.toString不会更改。因此它会在最深的递归级别终止。您需要在某个位置更新url,使其继续。例如,每次递归调用只执行一次。是的,这是家庭作业,我应该如何处理堆栈?不必是堆栈,只要您在第一个递归调用中使用数据结构举止粗鲁。