gpt4 book ai didi

java - HttpAsyncClient 和多线程 Jsoup 连接类之间有区别吗?

转载 作者:行者123 更新时间:2023-12-03 12:51:52 25 4
gpt4 key购买 nike

我正在用 Java 实现网络抓取工具。在尝试了一些我要抓取的网站之后,我想使用 Java 中并发 HTTP 连接的最佳实践。我目前正在使用 Jsoup's连接方法。我想知道是否可以创建线程并在这些线程内建立连接,类似于 HttpAsyncClient .

最佳答案

Jsoup不使用 HttpAsyncClient。 Jsoup 的 Jsoup.connect(String url)方法使用阻塞 URL.openConnection() 方法。

如果您想异步使用 Jsoup,您可以并行所有 Jsoup.connect()处决。在 Java 8 中,您可以使用并行流来执行此操作。假设您有一个要并行抓取的 URL 列表。看看下面的例子:

import org.jsoup.Jsoup;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

public class ConcurrentJsoupExample {

public static void main(String[] args) throws ExecutionException, InterruptedException {
final List<String> urls = Arrays.asList(
"https://google.com",
"https://stackoverflow.com/questions/48298219/is-there-a-difference-between-httpasyncclient-and-multithreaded-jsoup-connection",
"https://mvnrepository.com/artifact/org.jsoup/jsoup",
"https://docs.oracle.com/javase/7/docs/api/java/net/URL.html#openConnection()",
"https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html"
);

final List<String> titles = urls.parallelStream()
.map(url -> {
try {
return Jsoup.connect(url).get();
} catch (IOException e) {
return null;
}
})
.filter(Objects::nonNull)
.map(doc -> doc.select("title"))
.map(Elements::text)
.peek(it -> System.out.println(Thread.currentThread().getName() + ": " + it))
.collect(Collectors.toList());
}
}

这里我们定义了 5 个 URL,这个简单应用的目标是获取 <title> 的文本值。来自这些网站的 HTML 标签。发生的事情是我们使用 URL 列表创建并行流,并将每个 URL 映射到 Jsoup 的 Document对象 - .get()方法抛出已检查的异常,因此我们必须 try catch 它,如果发生异常,我们返回 null值(value)。全部null值按 .filter(Objects::nonNull) 过滤然后我们可以提取我们需要的元素 - <title> 的文本值在这种情况下标记。我还添加了 .peek()打印提取的值是什么以及它运行的线程名称是什么。示例性输出可能如下所示:

ForkJoinPool.commonPool-worker-1: java - Is there a difference between HttpAsyncClient and multithreaded Jsoup connection class? - Stack Overflow
main: Maven Repository: org.jsoup » jsoup
ForkJoinPool.commonPool-worker-4: URL (Java Platform SE 7 )
ForkJoinPool.commonPool-worker-2: URLConnection (Java Platform SE 7 )
ForkJoinPool.commonPool-worker-3: Google

最后我们调用.collect(Collectors.toList())终止流,执行所有转换并返回标题列表。

这只是一个简单的示例,但它应该给您提示如何并行使用 Jsoup。

或者您可以使用 url.parallelStream().forEach()如果类似功能的方法不能说服您:

urls.parallelStream().forEach(url -> {
try {
final Document doc = Jsoup.connect(url).get();
final String title = doc.select("title").text();

System.out.println(Thread.currentThread().getName() + ": " + title);

// do something with extracted title...

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

关于java - HttpAsyncClient 和多线程 Jsoup 连接类之间有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48298219/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com