m711083 2024-04-26 17:30 采纳率: 0%
浏览 11

关于#java爬虫#的问题,请各位专家解答!

img


import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class WebCrawler {

    public static void main(String[] args) {
        String url = "https://news.163.com/";
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)";

        try {
            Document doc = Jsoup.connect(url).userAgent(userAgent).get();
            Elements links = doc.select("a[href]");

            Set<String> allLinks = new HashSet<String>(); // 手动指定泛型类型为String
            for (Element link : links) {
                allLinks.add(link.attr("abs:href"));
            }

            ExecutorService executor = Executors.newFixedThreadPool(3);
            for (final String link : allLinks) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Document innerDoc = Jsoup.connect(link).userAgent(userAgent).get();
                            Elements innerLinks = innerDoc.select("a[href]");
                            for (Element innerLink : innerLinks) {
                                String innerUrl = innerLink.attr("abs:href");
                                System.out.println("内部链接:" + innerUrl);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }

            executor.shutdown();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

本人正在自学jsoup爬虫 想知道这段代码里面都调用了什么方法 我刚开始学jsoup 不知道该如何下手 希望能指教一二

多谢!

  • 写回答

7条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-26 17:30
    关注

    引自免费微信小程序:皆我百晓生

    在给定的Java代码片段中,主要使用了JSoup库进行网页抓取。下面是对整个代码的详细解释:

    1. 引入相关依赖:

      import org.jsoup.Jsoup;
      import org.jsoup.nodes.Document;
      import org.jsoup.nodes.Element;
      import org.jsoup.select.Elements;
      
      import java.io.IOException;
      import java.util.HashSet;
      import java.util.Set;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      
    2. 定义主类 WebCrawlermain 方法。

      public class WebCrawler {
          public static void main(String[] args) {
              ...
          }
      }
      
    3. 初始化要抓取的URL和User-Agent(浏览器标识):

      String url = "https://news.163.com/";
      String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)";
      
    4. 使用 Jsoup.connect(url) 连接到指定URL并获取HTML文档:

      Document doc = Jsoup.connect(url).userAgent(userAgent).get();
      
    5. 使用CSS选择器 a[href] 选取页面上所有带有href属性的 <a> 标签元素:

      Elements links = doc.select("a[href]");
      
    6. 创建一个HashSet allLinks 存储所有的外部链接,并遍历这些链接:

      Set<String> allLinks = new HashSet<>();
      for (Element link : links) {
          allLinks.add(link.attr("abs:href"));
      }
      
    7. 创建一个固定大小的线程池 ExecutorService 用于并发处理任务:

      ExecutorService executor = Executors.newFixedThreadPool(3);
      
    8. 遍历 allLinks 中的每个链接,创建一个新的Runnable任务并在线程池中执行它:

      for (final String link : allLinks) {
          executor.execute(new Runnable() {
              @Override
              public void run() {
                  ...
              }
          });
      }
      
    9. 在Runnable的任务中,对每个链接执行相同的步骤:连接、获取文档、提取内部链接并打印它们:

      try {
          Document innerDoc = Jsoup.connect(link).userAgent(userAgent).get();
          Elements innerLinks = innerDoc.select("a[href]");
          for (Element innerLink : innerLinks) {
              String innerUrl = innerLink.attr("abs:href");
              System.out.println("内部链接:" + innerUrl);
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
      
    10. 最后,关闭线程池以防止资源泄露:

      executor.shutdown();
      

    这个程序的主要功能是递归地抓取网易新闻网站(news.163.com)及其内嵌页面上的所有链接,并将内部链接打印出来。通过使用线程池,我们可以并发处理多个链接的抓取,提高抓取速度。

    如果你对某个特定的函数或概念不熟悉,可以参考以下说明:

    • Jsoup.connect(url).userAgent(userAgent).get(): 这一行连接到指定的URL,设置User-Agent并获取HTML文档。
    • doc.select("a[href]"): 使用CSS选择器找到HTML文档中的所有链接。
    • link.attr("abs:href"): 获取链接元素的绝对URL。
    • ExecutorService executor = Executors.newFixedThreadPool(3);: 创建一个包含3个线程的线程池。
    • executor.execute(new Runnable() {...}): 将任务提交到线程池执行。
    • e.printStackTrace(): 当捕获到异常时,打印堆栈跟踪信息。
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月26日