【发布时间】:2022-10-02 02:09:47
【问题描述】:
我正在尝试通过构建由this (gopl.io/ch8/crawl3) 建模的网络爬虫来了解有关 Kotlin 协程和通道的更多信息
这个想法是启动一组协程,它们循环通过链接通道访问linksToVisit,并将所有找到的链接推送到另一个通道foundLinks。
然后一个单独的 for 循环遍历 foundLinks,检查它们是否已经被访问,如果没有,则将它们推回 linksToVisit 以供协程拾取。
到目前为止,我的代码似乎可以正确访问所有链接,但不会终止 - 一旦访问了所有链接,它就会挂起。我做错了什么,是否可以以这种方式使用 for 循环?
这是代码:
fun crawl(startUrl: String) = runBlocking(CoroutineScope(Dispatchers.IO).coroutineContext) {
val linksToVisit = Channel<String>()
launch { linksToVisit.send(startUrl) }
val foundLinks = Channel<List<String>>()
repeat(20) {
launch {
for (channel in linksToVisit) {
val links = findLinks(channel)
launch { foundLinks.send(links) }
}
}
}
val visitedLinks = mutableMapOf<String, Boolean>()
for (links in foundLinks) {
for (link in links) {
if (!visitedLinks.contains(link)) {
visitedLinks[link] = true
linksToVisit.send(link)
}
}
}
}
其中findLinks(channel) 检索页面(使用JSoup)并返回找到的链接列表。
附带问题:JSoup 与协程兼容吗?
标签: kotlin kotlin-coroutines channel