我对 StormCrawler 很陌生,我第一次实现了网络爬虫,到目前为止我对这个产品非常满意!
我正在使用带有 Elastic 5.5.1 的 StormCrawler v1.5.1,并根据提供的“ESCrawlTopology.java”设置我的拓扑。
我希望能够在拓扑运行时更改起始 URL(种子)和跟随/不跟随 URL。到目前为止,我得到的是一个包含此配置的 redis-DB 和一个 URL-Filter,它使用 redis 从中读取其跟随-不跟随-模式。我还实现了一个 start-url spout,它从 redis 读取,检测更改并通过 status-updater 将新找到的 start-urls 发布到 elastic。到目前为止,此设置效果很好。
对于 follow-/no-follow 规则,我还实现了一个 spout,它检测更改并使用“DeleteByQuery”-Elastic-action 从 Elastic 中的“index”和“status”-Index 中删除所有不再匹配的 URL。我没有为此使用 Status-Updater 或 DeletionBolt。
即使这可行,但感觉不对,我确实看到了潜在的问题。首先,我不能使用状态更新器的缓存,因为删除不是通过此组件完成的,因此缓存不会更新,从而阻止状态更新器添加曾经添加、删除和再次添加的 URL。其次,当一个或多个 URL 被提取或解析而它们被排除并从“状态”和“索引”中删除时,我不确定结果。我希望处理中的 URL 被编入索引,尽管它们之前被排除在外。
我还尝试了一种设置,在该设置中,我将所有排除的 URL 发送到具有 ERROR 状态的状态更新程序。与 DeletionBolt 结合使用会导致 URL 从“index”-index 中取出。这似乎是一个更干净的解决方案 - 但是曾经被排除的 URL 永远不能再被重新索引,因为它们作为“错误”驻留在“状态”-索引中。
在我看来,最好的解决方案是:
- 使用状态“已移除”在“状态”索引中标记排除的 URL(目前不可用)
- 使所有组件(提取器、解析器...)都知道“已删除”状态以丢弃当前正在处理的排除 URL
- 实现一个清理过程,将所有“已删除”的 URL 发送到 DeletionBolt,并在确认时从“状态”中删除此 URL
目前我看不到在不对 StormCrawler 的核心组件进行重大调整的情况下实现这一点的方法,因为目前没有“已移除”这样的状态。
你对这个问题有什么想法,什么是可能的解决方案?