0

我正在使用网络抓取工具,但我无法解决连续第二天遇到的问题。

这种方法的问题是当机器人应该访问网站时,收集所有 URL,并将其中尚未访问的 URL 添加到 List< String> "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);
        }
    }
}
4

2 回答 2

0

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

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

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

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

        if (!visited.contains(x) && !toVisit.contains(x) && x.contains(stayAt)) { 
            toVisit.add(x);
        }
于 2020-04-25T13:14:25.330 回答
-1

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

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

希望能帮助到你

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;
    }
}
于 2020-04-25T09:49:08.543 回答