1

我正在创建一个简单的网络蜘蛛。它所做的只是接受一个 URL,下载 HTML 并提取剩余的 URL。然后它对每个新 URL 重复该过程。我还确保我不会两次访问同一个 URL,并且我限制了并发下载的数量。

在每个唯一的 URL 都用完之后(可能会运行几天、几周或直到我死了之后),我想执行一个操作,比如更新 UI 或简单地退出应用程序。

问题是,我不知道如何检测最后一个线程何时完成运行。

这个线程问题解决了吗?我是不是看错了问题?

一个想法是让每个线程保持活动状态,直到其所有子线程完成(加入)。问题是线程的数量呈指数增长。对于这样一个长时间运行的进程,它会很快耗尽操作系统资源。

4

1 回答 1

2

我不确定我们在说什么语言,所以我会笼统地说。

您需要为每个 URL 建立一个数据结构,以跟踪从中生成了多少“子”页面。每当一个 URL 被爬取时,它都会有一个“父”数据结构。每当找到新页面时,都会将其添加到父级的树数中。每当一个页面被爬取时,父级的树数就会减少。这需要以同步的方式完成,因为多个线程将对其进行更新。

您实际上可能想要保存整个 URL 结构。根 URL“http://foo.x/”有指向“/1.html”和“/2.html”的链接,所以它的子数是 2。根 URL 有一个null父级和“1”和“2” " 有根的父级。当“1.html”被爬取时,根的子节点数减为 1。但如果“1.html”内有 3 个链接,则根的计数增加到 4。如果你想跟踪树然后“1.html”子项计数变为 3,依此类推。然后,当“1.html”的子项之一被爬取时,“1.html”的计数变为 2,根 URL 的计数变为 3。

您当然希望保留线程,然后像您提到的那样稍后加入 - 您的线程数会爆炸。您应该使用线程池并将 URL 提交给蜘蛛,每个 URL 及其在 URL 树中的关联节点,以便它们可以被相同的线程蜘蛛蜘蛛。

当一个 URL 被爬取,并且子项计数变为 0 时,您就知道您已经爬取了整个树,并且该 URL 可以从工作列表中删除并移动到完成列表中。同样,这些列表需要同步,因为多个线程将在它们上运行。

希望这会有所帮助。

于 2012-05-24T13:59:20.953 回答