1

我正在构建一个网络爬虫,我已经实现了解析部分。现在我想将获得的 URI 存储到一个高效的数据结构中。我应该用什么??我正在使用 Jena 库进行解析。

4

5 回答 5

0

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

于 2012-09-22T18:46:02.037 回答
0

通常在网络爬虫应用程序中 - 您需要管理 url 以丢弃蜘蛛陷阱(有时称为“黑洞”),丢弃对同一页面的频繁访问,您还将使用 url 作为页面内容的全局标识符。

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

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

网络爬虫向优先队列询问要访问的 url。因此,只会首先访问具有最高优先级的 url 的页面。

您可以构建自己的散列函数,以最好的方式满足您的需求(例如 - 从 url 字符串中删除参数并从字符串的其余部分计算散列)。

于 2012-09-24T13:35:26.700 回答
0

哈希。

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

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

哈希 ['方案'] = 方案;

哈希 ['域'] = 域;

哈希 ['端口'] = 端口;

哈希 ['路径'] = 路径;

哈希['query_string'] = query_string;

哈希['fragment_id'] = fragment_id;

于 2012-09-22T18:13:18.877 回答
0

爬虫通常使用 aQueue来保存要检查的 URI,并Set在将 URI 插入上述队列并在检查后将 URI 放入集合之前检查重复项。

如果您的链接数量可以容纳在内存中,那么您可以将 aLinkedList作为队列,将 aHashSet作为集合。否则,您可以将外部数据库用于这两个目的,或者将队列服务器(如 ActiveMQ)用作队列,将数据库用作集合。

于 2012-09-22T18:38:23.997 回答
0

我猜你想自动丢弃重复项,所以没有 URI 被抓取两次?然后我会建议一个HashSet

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

于 2012-09-22T18:20:25.220 回答