【发布时间】:2011-04-12 22:41:42
【问题描述】:
在类似爬虫的项目中,我们有一个常见且广泛使用的任务来解析/扩展数千个 URL。假设我们有(非常简化的示例):
GET 'http://bit.ly/4Agih5' 请求返回 3xx 之一,我们跟随重定向到:
GET 'http://stackoverflow.com' 返回 200。所以 'stackoverflow.com' 是我们需要的结果。
任何网址(不仅是像 bit.ly 这样的知名缩短器)都可以作为输入。其中一些重定向一次,一些根本不重定向(在这种情况下结果是 URL 本身),一些重定向多次。 我们的任务是尽可能地跟踪模仿浏览器行为的所有重定向。 一般来说,如果我们有一些 URL A 解析器应该返回我们 URL B 应该与 A 相同在某些浏览器中打开。
到目前为止,我们使用 Java、线程池和简单的URLConnection 来解决这个任务。优点很明显:
-
简单 - 只需创建
URLConnection,设置跟随重定向就可以了(几乎); - 良好的 HTTP 支持 - Java 提供了我们尽可能模仿浏览器所需的一切:自动跟踪重定向、cookie 支持。
不幸的是,这种方法也有缺点:
-
性能 - 线程不是免费的,
URLConnection在getInputStream()之后立即开始下载文档,即使我们不需要它; -
内存占用 - 不确定,但似乎
URL和URLConnection是相当重的对象,并且在getInputStream()调用之后再次缓冲 GET 结果。
是否有其他解决方案(或对此进行改进)可以显着提高速度并减少内存消耗?大概,我们需要类似的东西:
- 基于java.nio的高性能轻量级Java HTTP客户端;
- 使用 poll() 或 select() 的 C HTTP 客户端;
- 一些现成的库,可以解析/扩展 URL;
【问题讨论】:
-
你试过 Apache Nutch 爬虫吗?
-
某些网站使用元标记或 Javascript 进行重定向,因此您很可能希望使用浏览器来获得明确的答案。
-
@Abdullah Jibaly 是的,我知道。其中最重要的是,我们以特定于站点的方式处理以获得最终目的地。正如我所说,行为应该尽可能接近浏览器,而不是完全相同。考虑到我们需要处理数千个 URL,我认为这不是我们处理 JS 的方式。
标签: java c http web-crawler