C # Crawler Перемещение однопоточного вызова WebClient в многопоточность

1

В настоящее время у нас есть веб-искатель для наших клиентов, у которых нет возможности предоставить нам xml файл. Список создается, поэтому мне нужно иметь более эффективный способ обхода этих сайтов. Логика сканера проста:

Pass in www.example.com/widgets
Store the html and pass it to crawler function

crawl widgets page 1
 IF widgets page 1 is the end of their product list
   stop
 else 
   go to widgets page 2

Это повторяется для каждого сайта в очереди. Как вы можете видеть, если на сайте 1 есть 5000 продуктов, сайт 2 не может действовать до тех пор, пока он не будет выполнен. Что было бы лучшим способом для многопоточного потока, чтобы я мог ограничить количество запросов, которые я делаю для каждого сайта, но одновременно захватить несколько сайтов? Я попробовал Parallel.ForEach, но результат был очень спорадическим и непредсказуемым. В настоящее время мы справляемся с этим, когда "группы" магазинов блокируются и одновременно используют диспетчер задач Windows. вот пример кода:

foreach(site in ListofSites)
{
  int page = 1;
  bool continue_crawling = true;
  while(continue_crawling)
  {
    HtmlDocument doc = new HtmlDocument();
    var htmlWeb = new HtmlWeb();
    htmlWeb.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
    doc = htmlWeb.Load(URL + page);
    string html = doc.DocumentNode.OuterHtml;
    continue_crawling = ParseFile(html);
    page++;
  }
}

private bool Parse(string html)
{
  //parse the file and see if we have enough data
 return endofproduct;
}
Теги:
multithreading
web-crawler
asynchronous

1 ответ

1

Все HTTP-запросы С# пройдут через ServicePoint для домена URL-адреса запроса. ServicePoint наследует ConnectionLimit из ServicePointManager.DefaultConnectionLimit. Значение по умолчанию - 2, в соответствии с "практикой хороших клиентов" RFC2616:

Однопользовательский клиент НЕ ДОЛЖЕН поддерживать более двух соединений с любым сервером или прокси.

Все, что переводится, заключается в том, что запуск 1 HTTP-запросов gazzilion для URL-адресов в том же домене будет отправлять только не более 2 HTTP-запросов, а другой не запускается, если только он не завершится. Для достижения более высокого уровня параллелизма вам необходимо увеличить лимит подключения ServicePoint для домена, представляющего интерес. Выполнение параллельного ввода-вывода с использованием потоков (включая PTL) довольно примитивно, но должно работать, если вы исправите ограничение. Разумеется, предпочтительнее использовать асинхронный ввод-вывод.

  • 0
    Сделает ли это невозможным тот факт, что я должен знать, когда попаду в конец списка продуктов? Если бы я отправил 4 запроса на сайт s и вернулся на страницы 1-4, но конечным продуктом была страница 2. Мне бы пришлось уведомить все остальные темы этого сайта, чтобы они прекратили их текущее чтение.
  • 0
    Вы должны знать, что вы ползаете ... Зачем спрашивать bforbinvalid url для начала, вы должны перейти по ссылке.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню