用于在Java中存储Web爬网程序的URI的最佳高效数据结构

时间:2012-09-22 18:07:50

标签: java database data-structures web-crawler

我正在建立一个Web Crawler我已经实现了解析部分。现在我想将获得的URI存储到一个有效的数据结构中。我该怎么用?我正在使用Jena库进行解析。

5 个答案:

答案 0 :(得分:0)

哈希。

例如:URL:scheme:// domain:port / path?query_string#fragment_id。

将URL解析为字符串后,将URL存储为:

hash ['scheme'] = scheme;

hash ['domain'] = domain;

hash ['port'] = port;

hash ['path'] = path;

hash ['query_string'] = query_string;

hash ['fragment_id'] = fragment_id;

答案 1 :(得分:0)

我想你想自动丢弃重复项,所以没有URI被抓取两次?那我建议HashSet

它会自动丢弃重复项,并且在最佳情况下插入复杂度仍然保持不变。请注意,当您使用自己的类来表示URI而不是默认类java.net.URI时,您必须覆盖URI类的int hashCode()方法以返回URI字符串的基于文本的哈希。 Object的默认方法为每个对象创建唯一的哈希码,即使内容相同也是如此。

答案 2 :(得分:0)

抓取程序通常使用Queue来保留要检查的URI,并附带Set以检查重复项,然后将URI插入上述队列中,并在检查后将URI放入集合中。

如果您的链接数量适合内存,则可以只有LinkedList作为队列,HashSet作为集合。否则,您可以将外部数据库用于两个目的,或者将排队服务器(如ActiveMQ)用作队列,将数据库用作集合。

答案 3 :(得分:0)

我会将要处理的URI队列存储在Redis(http://redis.io/)中处理已经处理过的URI。 Redis是一个非常快速的半持久键值存储,它支持各种数据结构,包括列表(URI队列)和散列(映射)。这样,这些数据结构将在Java应用程序重启后继续存在。您也可以运行多个应用实例,而无需通过Redis进行通信。

答案 4 :(得分:0)

通常在网络抓取应用程序中 - 您需要管理网址以丢弃spider traps(有时称为“黑洞”),放弃频繁访问同一网页,您还将使用网址作为网页的全局标识符内容。

但另一个有趣的时刻 - 是丢弃两次访问相同的网址是错误的因为网页内容可能会及时更改)。

因此,满足这些要求的最佳方法是使用某种优先级队列并将每个网址与元组相关联:{url, hash(url)}。当你获得新的url时 - 只计算它的哈希值,如果你的数据库记录中有相同的哈希值 - 只需为此URL设置低优先级并将其放入优先级队列。

Web爬网程序要求url的优先级队列访问。因此,只有具有最高优先级的网页才会被访问。

您可以以最佳方式构建自己的哈希函数(例如 - 从url字符串中删除参数并从字符串的其余部分计算哈希值)。