用于解析/扩展数千个URL的工具/库

时间:2011-04-12 22:41:43

标签: java c http web-crawler

在类似爬虫的项目中,我们有一个共同且广泛使用的任务来解析/扩展数千个URL。假设我们有(非常简化的例子):

http://bit.ly/4Agih5

GET'http://bit.ly/4Agih5'请求返回3xx中的一个,我们按照重定向到右边:

http://stackoverflow.com

GET'http://stackoverflow.com'返回200.所以'stackoverflow.com'是我们需要的结果。

允许任何URL(不仅仅是bit.ly等众所周知的缩写词)作为输入。其中一些重定向一次,一些不重定向(在这种情况下结果是URL本身),一些重定向多次。 我们的任务是尽可能地遵循所有重定向模仿浏览器行为。一般来说,如果我们有一些网址A解析器应该返回我们的网址B,它应该与如果在某个浏览器中打开了A

到目前为止,我们使用Java,线程池和简单URLConnection来解决此任务。优势显而易见:

  • 简单 - 只需创建URLConnection,设置跟随重定向即可(几乎);
  • 良好的HTTP支持 - Java提供了尽可能模仿浏览器所需的一切:自动跟踪重定向,cookie支持。

不幸的是,这种方法也有缺点:

  • 性能 - 线程不是免费的,URLConnection会在getInputStream()之后立即开始下载文档,即使我们不需要它;
  • 内存占用 - 不确切但看起来URLURLConnection是非常重的对象,并且在{{1}之后再次缓冲GET结果呼叫。

是否有其他解决方案(或改进此解决方案)可能会显着提高速度并降低内存消耗?据推测,我们需要以下内容:

  • 基于java.nio的高性能轻量级Java HTTP客户端;
  • 使用poll()或select();
  • 的C HTTP客户端
  • 解析/扩展网址的一些现成的库;

2 个答案:

答案 0 :(得分:1)

我会使用selenium脚本从队列中读取网址并GET。然后每个浏览器等待大约5秒钟以查看是否发生重定向,如果是,则将新的重定向URL重新放入队列以供下一个要处理的实例。您可以根据需要同时运行多个实例。

<强>更新

如果您只关心Location标头(大多数非JS或元重定向使用的),只需检查它,您就不需要获取inputStream

HttpURLConnection.setFollowRedirects(false);
URL url = new URL("http://bit.ly/abc123");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
String newLocation = conn.getHeaderField("Location");

如果填充了newLocation,那么请将该网址粘贴回队列,然后在下一轮进行。

答案 1 :(得分:1)

您可以使用Python,Gevent和urlopen。将this gevent exampelthe redirect handling in this SO question结合使用。

我不推荐Nutch,它设置起来非常复杂并且有很多依赖项(Hadoop,HDFS)。