Мне необходимо распарсить сайт с гос.закупками за каждый месяц года. Как сделать выполнение данных задач параллельными?
public async Task<IList<Auction>> GetResultAuction(string dateFrom, string dateTo, string fileName)
{
Console.WriteLine($"Start: {fileName}");
var auctions = new List<Auction>();
var config = Configuration.Default.WithDefaultLoader();
var context = BrowsingContext.New(config);
var pages = await GetPagesAsync(dateFrom, dateTo);
foreach (var page in pages.ToArray())
{
string number = page.Url.Split("=").Last();
string url =
$"https://zakupki.gov.ru/epz/order/notice/ea20/view/supplier-results.html?regNumber={number}";
var document = await context.OpenAsync(url);
var cells = document.QuerySelectorAll("#supplier-def-result-participant-table-28901226 .blockInfo__table.tableBlock .tableBlock__body .tableBlock__row td:nth-child(3)")
.Select(x => x.TextContent.Trim()).ToArray();
if (cells is { Length: > 0 } && cells[1] == cells[2])
{
var auction = new Auction
{
Number = number,
Object = document.QuerySelector(".cardMainInfo__content")?.TextContent,
Url = $"https://zakupki.gov.ru/epz/order/notice/ea20/view/common-info.html?regNumber={number}"
};
auctions.Add(auction);
}
}
return auctions;
}
private async Task<IList<Page>> GetPagesAsync(string dateFrom, string dateTo)
{
var pages = new List<Page>();
var config = Configuration.Default.WithDefaultLoader();
var context = BrowsingContext.New(config);
for (int i = 1; i <= 100; i++)
{
string url =
$"https://zakupki.gov.ru/epz/order/extendedsearch/results.html?morphology=on&search-filter=+%D0%94%D0%B0%D1%82%D0%B5+%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%89%D0%B5%D0%BD%D0%B8%D1%8F&pageNumber={i}&sortDirection=false&recordsPerPage=_200&showLotsInfoHidden=false&sortBy=PUBLISH_DATE&fz44=on&pc=on&placingWayList=EA44%2CEAP44%2CEA20%2CEAP20%2CEAB44%2CEAO44%2CEAO20%2CEAB20%2CEEA44%2CEEA20&selectedLaws=FZ44&priceFromGeneral=50000&priceToGeneral=10000000&currencyIdGeneral=1&publishDateFrom={dateFrom}&publishDateTo={dateTo}";
var document = await context.OpenAsync(url);
var cells = document.QuerySelectorAll(".registry-entry__header-mid__number a")
.Select(x => x.GetAttribute("href"));
foreach (var cell in cells)
{
var page = new Page
{
Url = cell
};
pages.Add(page);
}
}
return pages;
}
Я подумал, что будет правильно создать коллекцию задач и вызвать метод await Task.WhenAll()
Не возникнут ли у меня в этом коде проблемы с конкуренцией?
var tasks = new List<Task<IList<Auction>>>();
ParserService parserService = new ParserService();
tasks.Add(parserService.GetResultAuction("01.01.2021", "31.01.2021", "January"));
tasks.Add(parserService.GetResultAuction("01.02.2021", "27.02.2021", "February"));
var result = await Task.WhenAll(tasks);
Не возникнут ли у меня в этом коде проблемы с конкуренцией?- это зависит от используемых общих между потоками ресурсов. Сходу таких не вижу. Если сильно распараллелитесь, можете получить бан по IP от веб-сервера, который посчитает вас ботом (и правильно сделает). Так что знайте меру. – aepot Feb 16 '22 at 15:45