首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >深度优先搜索

深度优先搜索
EN

Stack Overflow用户
提问于 2015-01-23 01:10:08
回答 1查看 498关注 0票数 1

我对阿尔戈斯和DS很陌生。我需要使用BFS实现一个网络爬虫。我是这么来的far...but,因为我使用一个队列,我无法得到深度。

代码语言:javascript
复制
public void BFS() {
    String link = "";
    while (mainSet.size() <= 100 && depth < 5) {
        if (queue.size() >=1) {
            System.out.println(queue);
            link = queue.removeFirst();
            System.out.println("Link shifted from queue!");
            System.out.println(link);
            String html = fetchContent(link);
            fetchLinks(html);
        } else {
            System.out.println("Completed!!");
            break;
        }
    }
}

public String fetchContent(String strLink) {
    String html = "";
    URLConnection connection = null;
    Scanner scanner = null;
    try {
        connection = new URL(strLink).openConnection();
        scanner = new Scanner(connection.getInputStream());
        scanner.useDelimiter("\\Z");
        if (scanner.hasNext()) {
            html = scanner.next();
            visited.add(strLink);
        }
    } catch (Exception ex) {

    } finally {
        if (scanner!= null)
            scanner.close();
    }
    return html;
}

public void fetchLinks(String html) {
    Document doc = Jsoup.parse(html);
    Elements links = doc.select("a[href]");

    for (Element link: links)  {
        String group = link.attr("href");
        if ((!group.contains(".css")) && (!group.contains(".ico")) && (!group.contains(".jpg")) && (!group.contains(" "))
                && (!group.contains(".gif")) && (!group.contains(".pdf")) && (!group.contains(".zip")) && (!group.contains(".asc")) 
                && (!group.contains(".rar")) && (!group.contains(".png")) && (!group.contains(".7z")) 
                && (!group.contains(".djvu")) && (!group.contains(".chm")) && (!group.contains(".mp3")) 
                && (!group.contains(".ogg")) && (!group.contains(".rm")) && (!group.contains(".wav")) 
                && (!group.contains("mailto:")) && (!group.contains("#")) && (!group.contains(".xml")) 
                && (!group.contains(".js")) && (!group.contains("news:")) && (!group.contains("mail:")) 
                && (!group.contains(".txt")) && (!group.contains(".bz2")) && (!group.contains(".gz"))
                && (!group.contains("javascript:")) && (!group.contains("exe")) && (!group.contains("vbs"))) {
            group = group.replaceAll("'", "");
            group = group.replaceAll("\"", "");

            if ((group.indexOf("http") == -1)) {
                if (group.charAt(0) != '/') {
                    group = parent + group;
                } else if(group.charAt(0) == '/') {
                    group = scheme + "://" + authority + group;
                }
                System.out.println("RelLink: " + group);
                mainSet.add(group);
            } else if (group.startsWith(parent)) {
                System.out.println("SeedLink: " + group);
                mainSet.add(group);
            }
            if (!visited.contains(group)) {
                if (group.startsWith(parent)) {
                    queue.add(group);
                }
            }
        }
    }
}

我想限制爬行器的深度。此外,我还想知道如何从队列中删除重复项。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-23 02:10:35

要限制深度,可以创建一个封装深度和要获取的页面的类。您甚至可以将一些函数放到该类中:

代码语言:javascript
复制
public class Page {
  private final int depth;
  private final String url;

  public Page(String url, int depth) {
    this.url = url;
    this.depth = depth;
  }

  private Set<String> fetchLinks(html) {
    // use your implementation, but return the links instead
    // of adding them to a queue. Using a set removes duplicates
  }

  /**
    * Fetches the URL represented by this page, and
    * add pages to the queue for all pages linked to
    * by the page.
    */
  public void visitPage(Queue<Page> workQueue) {
     String html = fetchContent(url);

     if (depth == 5) {
       // in too deep!
       return;
     }

     for (String link : fetchLinks(html)) {
       workQueue.add(new Page(link, depth + 1));
     }
   } 
}

至于删除重复项,您可以使用LinkedHashSet而不是Queue (以防止队列中的重复),也可以维护获取页面的Set (以防止多次获取页面)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28101500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档