同时获取多个HTML页面的有效方法

时间:2013-01-17 01:49:08

标签: java multithreading http

所以我正在为某个网站进行网络抓取。问题是:

给定一组URL(大约100到1000),我想以有效的方式检索每个URL的HTML,特别是时间。我需要每5分钟完成1000次请求。

这通常意味着使用一个线程池来处理来自一组尚未请求的URL的请求。但在开始实施之前,我认为值得在此问一下,因为我认为在进行网页抓取或网络抓取时这是一个相当常见的问题。

有没有我需要的图书馆?

4 个答案:

答案 0 :(得分:1)

  

所以我正在为某个网站进行网络抓取。

您是在抓一台服务器还是网站从其他多台主机上刮下来?如果它是前者,则您正在抓取的服务器可能不喜欢来自单个i / p的过多并发连接。

如果是后者,这实际上是关于应该从机器打开多少出站连接的一般问题。有物理限制,但是相当大。实际上,它取决于客户端的部署位置。连接性越好,它可以容纳的连接数量越多。

您可能希望查看优秀下载管理器的源代码,以查看它们是否对出站连接数有限制。

绝对是用户异步i / o,但你仍然可以很好地限制数量。

答案 1 :(得分:0)

我首先要研究asynchronous communication。然后看看Netty

请记住,加载网页的速度总是有限制的。对于普通的家庭连接,它将是大约一秒钟。在编写应用程序时请考虑这一点。

答案 2 :(得分:0)

您的带宽利用率将是您检索的所有HTML文档的总和(加上一点开销),无论您如何对其进行切片(尽管某些Web服务器可能支持压缩的HTTP流,因此请务必使用能够接受的客户端)它们)。

最佳并发线程数在很大程度上取决于您与相关网站的网络连接。只有实验才能找到最佳数字。您当然可以使用一组线程来检索HTML文档和一组单独的线程来处理它们,以便更容易找到合适的平衡。

我是HTML Agility Pack的忠实粉丝,在.NET世界中进行网页抓取,但无法针对Java提出具体建议。以下问题可能有助于找到一个好的,基于Java的抓取平台

Web scraping with 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();