所以我正在为某个网站进行网络抓取。问题是:
给定一组URL(大约100到1000),我想以有效的方式检索每个URL的HTML,特别是时间。我需要每5分钟完成1000次请求。
这通常意味着使用一个线程池来处理来自一组尚未请求的URL的请求。但在开始实施之前,我认为值得在此问一下,因为我认为在进行网页抓取或网络抓取时这是一个相当常见的问题。
有没有我需要的图书馆?
答案 0 :(得分:1)
所以我正在为某个网站进行网络抓取。
您是在抓一台服务器还是网站从其他多台主机上刮下来?如果它是前者,则您正在抓取的服务器可能不喜欢来自单个i / p的过多并发连接。
如果是后者,这实际上是关于应该从机器打开多少出站连接的一般问题。有物理限制,但是相当大。实际上,它取决于客户端的部署位置。连接性越好,它可以容纳的连接数量越多。
您可能希望查看优秀下载管理器的源代码,以查看它们是否对出站连接数有限制。
绝对是用户异步i / o,但你仍然可以很好地限制数量。
答案 1 :(得分:0)
我首先要研究asynchronous communication。然后看看Netty。
请记住,加载网页的速度总是有限制的。对于普通的家庭连接,它将是大约一秒钟。在编写应用程序时请考虑这一点。
答案 2 :(得分:0)
您的带宽利用率将是您检索的所有HTML文档的总和(加上一点开销),无论您如何对其进行切片(尽管某些Web服务器可能支持压缩的HTTP流,因此请务必使用能够接受的客户端)它们)。
最佳并发线程数在很大程度上取决于您与相关网站的网络连接。只有实验才能找到最佳数字。您当然可以使用一组线程来检索HTML文档和一组单独的线程来处理它们,以便更容易找到合适的平衡。
我是HTML Agility Pack的忠实粉丝,在.NET世界中进行网页抓取,但无法针对Java提出具体建议。以下问题可能有助于找到一个好的,基于Java的抓取平台
答案 3 :(得分:0)
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();