所以我正在为某个网站进行网络抓取。问题是:
给定一组 URL(按 100 到 1000 的顺序),我想以一种有效的方式检索每个 URL 的 HTML,特别是在时间方面。我需要能够每 5 分钟处理 1000 个请求。
这通常意味着使用线程池来执行来自一组尚未请求的 url 的请求。但在开始实施之前,我认为值得在这里问一下,因为我相信在进行网络抓取或网络爬虫时这是一个相当普遍的问题。
有没有我需要的图书馆?
所以我正在为某个网站进行网络抓取。问题是:
给定一组 URL(按 100 到 1000 的顺序),我想以一种有效的方式检索每个 URL 的 HTML,特别是在时间方面。我需要能够每 5 分钟处理 1000 个请求。
这通常意味着使用线程池来执行来自一组尚未请求的 url 的请求。但在开始实施之前,我认为值得在这里问一下,因为我相信在进行网络抓取或网络爬虫时这是一个相当普遍的问题。
有没有我需要的图书馆?
所以我正在为某个网站进行网络抓取。
您是在抓取单个服务器还是从多个其他主机抓取网站?如果是前者,那么您正在抓取的服务器可能不喜欢来自单个 i/p 的太多并发连接。
如果是后者,这确实是一个关于您应该从机器打开多少出站连接的一般问题。有物理限制,但它相当大。实际上,这将取决于该客户端的部署位置。连接性越好,它可以容纳的连接数就越多。
您可能想查看一个好的下载管理器的源代码,看看它们是否对出站连接数有限制。
绝对是用户异步 i/o,但您仍然可以很好地限制数量。
您的带宽利用率将是您检索到的所有 HTML 文档的总和(加上一点开销),无论您如何对其进行切片(尽管某些 Web 服务器可能支持压缩的 HTTP 流,因此请务必使用能够接受它们的客户端)。
并发线程的最佳数量在很大程度上取决于您与相关站点的网络连接。只有实验才能找到最佳数字。您当然可以使用一组线程来检索 HTML 文档,并使用一组单独的线程来处理它们,以便更容易找到正确的平衡点。
我是 .NET 世界中用于 Web 抓取的HTML Agility Pack的忠实粉丝,但无法对 Java 提出具体建议。以下问题可能有助于找到一个好的、基于 Java 的抓取平台
http://wwww.Jsoup.org仅用于报废部分!我认为你应该自己实现线程池。
更新
如果这种方法适合您的需要,您可以在此处下载完整的类文件:http: //codetoearn.blogspot.com/2013/01/concurrent-web-requests-with-thread.html
AsyncWebReader webReader = new AsyncWebReader(5/*number of threads*/, new String[]{
"http://www.google.com",
"http://www.yahoo.com",
"http://www.live.com",
"http://www.wikipedia.com",
"http://www.facebook.com",
"http://www.khorasannews.com",
"http://www.fcbarcelona.com",
"http://www.khorasannews.com",
});
webReader.addObserver(new Observer() {
@Override
public void update(Observable o, Object arg) {
if (arg instanceof Exception) {
Exception ex = (Exception) arg;
System.out.println(ex.getMessage());
} /*else if (arg instanceof List) {
List vals = (List) arg;
System.out.println(vals.get(0) + ": " + vals.get(1));
} */else if (arg instanceof Object[]) {
Object[] objects = (Object[]) arg;
HashMap result = (HashMap) objects[0];
String[] success = (String[]) objects[1];
String[] fail = (String[]) objects[2];
System.out.println("Failds");
for (int i = 0; i < fail.length; i++) {
String string = fail[i];
System.out.println(string);
}
System.out.println("-----------");
System.out.println("success");
for (int i = 0; i < success.length; i++) {
String string = success[i];
System.out.println(string);
}
System.out.println("\n\nresult of Google: ");
System.out.println(result.remove("http://www.google.com"));
}
}
});
Thread t = new Thread(webReader);
t.start();
t.join();