Сложность: medium
Учитывая URL startUrl и интерфейс HtmlParser, реализуйте многопоточный веб-краулер, который будет просматривать все ссылки, находящиеся под тем же именем хоста, что и startUrl. Верните все URL, полученные вашим веб-краулером, в любом порядке.
Ваш краулер должен: Начинать со страницы: startUrl Вызывать HtmlParser.getUrls(url), чтобы получить все URL с веб-страницы данного URL. Не просматривать одну и ту же ссылку дважды. Исследовать только те ссылки, которые находятся под тем же именем хоста, что и startUrl.
Пример:
Input:
urls = [
"http://news.yahoo.com",
"http://news.yahoo.com/news",
"http://news.yahoo.com/news/topics/",
"http://news.google.com",
"http://news.yahoo.com/us"
]
edges = [[2,0],[2,1],[3,2],[3,1],[0,4]]
startUrl = "http://news.yahoo.com/news/topics/"
Output: [
"http://news.yahoo.com",
"http://news.yahoo.com/news",
"http://news.yahoo.com/news/topics/",
"http://news.yahoo.com/us"
]
👨💻 Алгоритм:
1⃣Извлечь имя хоста из startUrl.
Использовать многопоточность для обработки URL-адресов.
2⃣Хранить посещенные URL-адреса, чтобы избежать повторного посещения.
3⃣Использовать HtmlParser для получения URL-адресов с веб-страниц.
😎 Решение:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
public class HtmlParser {
public List<string> GetUrls(string url) {
return new List<string>();
}
}
public class Solution {
private ConcurrentDictionary<string, bool> visited = new ConcurrentDictionary<string, bool>();
private string hostname;
private HtmlParser htmlParser;
public IList<string> Crawl(string startUrl, HtmlParser htmlParser) {
this.hostname = new Uri(startUrl).Host;
this.htmlParser = htmlParser;
var tasks = new List<Task>();
visited.TryAdd(startUrl, true);
tasks.Add(Task.Run(() => Visit(startUrl)));
Task.WaitAll(tasks.ToArray());
return visited.Keys.ToList();
}
private async Task Visit(string url) {
foreach (var nextUrl in htmlParser.GetUrls(url)) {
if (new Uri(nextUrl).Host == hostname && visited.TryAdd(nextUrl, true)) {
await Visit(nextUrl);
}
}
}
}
Ставь 👍 и забирай 📚 Базу знаний