【问题标题】:.contains() problem/looks like it doesnt work.contains() 问题/看起来不起作用
【发布时间】:2020-08-08 21:58:16
【问题描述】:

我正在研究网络爬虫,但我连续第二天遇到的问题无法解决。

这种方法的问题是当机器人应该访问网站时,收集所有的 URL,并将其中没有访问过的 URL 添加到 List "toVisit"

有问题的代码:

Elements temp = userAgent.visit(currentUrl).findEvery("<a href>");
for (Element e : temp) {
    String x = e.getAt("href");
    if(!visited.contains(x)) { 
            toVisit.add(x);
    }
}

但是,if 语句没有过滤(或以我没有发现的方式过滤)url,我不知道为什么。

我尝试删除“!”在语句中创建一个 else 部分并粘贴 toVisit.add(x) 那里,但它没有帮助。

当我打印每个网址时,机器人会访问相同的网址两次甚至五次。

编辑(已访问定义)

static List<String> visited = new ArrayList<String>();

EDIT2(完整代码)

import java.util.ArrayList;
import java.util.List;
import com.jaunt.*;

public class b03 {

    static String currentUrl = "https://stackoverflow.com";
    static String stayAt = currentUrl;
    static String searchingTerm = "";
    static int toSearch = 50;

    static List<String> toVisit = new ArrayList<String>();
    static List<String> visited = new ArrayList<String>();

    static UserAgent userAgent = new UserAgent();   

    public static void main(String[] args) {
        System.out.println("*started searching...*");

        while(visited.size() < toSearch)
            visitUrl(currentUrl);

        System.out.println("\n\n*done*\n\n");
    }

    public static void visitUrl(String url) {
            visited.add(url);
            evaluateUrls();
            searchTerm();
            toVisit.remove(0);
            currentUrl = toVisit.get(0);
    }

    public static void searchTerm() {
        //if(userAgent.doc.getTextContent().contains(searchingTerm)) 
            System.out.println(visited.size() +") "+ currentUrl);
    }

    public static void evaluateUrls() {
        try {
            Elements temp = userAgent.visit(currentUrl).findEvery("<a href>");
            for (Element e : temp) {
                String x = e.getAt("href");
                if(!visited.contains(x) && x.contains(stayAt)) { 
                        toVisit.add(x);
                }
            }
        }catch (Exception e) {
            System.out.println(e);
        }
    }
}

【问题讨论】:

  • visited 定义在哪里?
  • 不相关的旁注:使访问的集合而不是列表。对于大型列表,列表查找('contains()')非常慢。

标签: java string contains jaunt-api


【解决方案1】:

您的机器人多次访问某些网址,因为您将它们多次添加到 toVisit 列表中。

为了说明这一点:假设您的机器人在 stackoverflow 网站上找到的前几个链接是指向“主页”(stackoverflow.com)、标签 (stackoverflow.com/tags)、用户 (stackoverflow.com/用户)和作业(stackoverflow.jobs),您的机器人会将其中三个添加到toVisit 列表中。

接下来它会访问标签页面 (stackoverflow.com/tags)。此页面再次包含指向与以前相同的四个 url 的链接。由于您尚未访问用户和工作子页面,因此它将第二次将它们添加到 toVisit 列表中。

要解决此问题,您应该只将不在visited 列表中的网址添加到toVisit 列表 不在toVisit 列表中:

        if (!visited.contains(x) && !toVisit.contains(x) && x.contains(stayAt)) { 
            toVisit.add(x);
        }

【讨论】:

    【解决方案2】:

    由于 jaunt 库,我无法尝试此代码

    拆分您的代码,使其可读。 尽量不要使用“静态”。

    希望对你有帮助

    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    import com.jaunt.*;
    
    public class B03 {
    
        static String currentUrl = "https://stackoverflow.com";
        static String stayAt = currentUrl;
        static String searchingTerm = "";
        static int toSearch = 50;
    
        static List<String> toVisit = new ArrayList<String>();
        static List<String> visited = new ArrayList<String>();
    
        static UserAgent userAgent = new UserAgent();
    
        public static void main(String[] args) {
            System.out.println("*started searching...*");
    
            toVisit.add(currentUrl);
    
            while(toVisit.size() > 0 && visited.size() < toSearch){
                visitUrl(toVisit.get(0));
            }
    
            System.out.println("\n\n*done*\n\n");
        }
    
        public static void visitUrl(String url) {
            List<String> ee = evaluateUrls(url);
            searchTerm(url);
    
            visited.add(url);
            toVisit.remove(url);
            toVisit.addAll(ee.stream().filter( e -> !visited.contains(e)).collect(Collectors.toList()));
    
            toVisit.remove(0);
        }
    
        public static void searchTerm(String currentUrl) {
            //if(userAgent.doc.getTextContent().contains(searchingTerm))
            System.out.println(visited.size() +") "+ currentUrl);
        }
    
        public List<String> evaluateUrls(String currentUrl) {
            List<String> subUrls = new ArrayList<>();
            try {
                Elements temp = userAgent.visit(currentUrl).findEvery("<a href>");
                for (Element e : temp) {
                    String x = e.getAt("href");
                    subUrls.add(x);
                }
            }catch (Exception e) {
                System.out.println(e);
            }
            return subUrls;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-09
      • 1970-01-01
      • 2012-04-01
      • 2020-04-04
      • 2016-06-15
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多