Для оценки контрагента довольно полезную информацию можно получить с сайта «ЕИС закупки», в частности из реестра недобросовестных поставщиков. Расскажу, как быстро проверить контрагентов, имея список ИНН.

Нахождение контрагента в реестре недобросовестных поставщиков / подрядных организаций вероятнее всего повлияет на решение сотрудничества с ним, так и на формирование резервов под него (например, в банковском кредитовании).
Для быстрой проверки, когда ИНН заемщиков слишком много, был написан код на c# для удобного поиска по этому списку:
Сначала из перечня ИНН формируем list:
List<string> INNs = new List<string>(); using(StreamReader sr=new StreamReader(path/to/file)) { string line; while ((line = sr.ReadLine()) != null) { INNs.Add(line.Trim()); } }
Посмотрим, какую информацию можно получить из реестра:

Дальше создаем класс поставщика с той информацией, которую можно собрать. Применим методы для возврата названий и значений полей.
public class Provider { public string INN { get; set; } public string Name { get; set; } public DateTime? DateAdd { get; set; } = null; public DateTime? DateUpdate { get; set; } = null; public DateTime? DateEnd { get; set; } = null; public string FZ { get; set; } public string SomethingNum { get; set; } public string Country { get; set; } public string Url { get; set; } public Provider() { } public string GetTitle() { return "inn\tName\tDateAdd\tDateUpdate\tDateEnd\tFZ\tSomethingNum"; } public string GetStr() { return this.INN + "\t" + this.Name + "\t" + this.DateAdd + "\t" + this.DateUpdate + "\t" + this.DateEnd + "\t" + this.FZ + "\t" + this.SomethingNum; } }
Изначально я хотел в конструкторе написать код по получению информации, но возникли случаи, когда возвращается несколько значений поиска, например, поставщик попадал несколько раз в реестр, так что я отказался от такой идеи.

Поэтому функция по получению информации реализована в отдельном классе, а заодно и метод для того, чтобы записать результат из списка:
В первой части функции идет запрос к сайту и получение html.
Далее смотрим на наличие блоков с информацией:
a. если их нет, то идем на шаг 4;
b. если есть, то идем дальше по функции;
идем по блокам циклом и заполняем поля класса в соответствие с названием;
a. если ИНН поисковой не соответствует инн в блоке то переходим на следующую итерацию;
b. если соответствует идем дальше, добавляем даты и класс добавляем в список;
возвращаем список.
public static class Metods { public static void Write(this List<Provider> providers) { using (StreamWriter sw = new StreamWriter("res.txt")) { sw.WriteLine(new Provider().GetTitle()); foreach (Provider provider in providers) { sw.WriteLine(provider.GetStr()); } } } public static List<Provider> GetProviderFromSite(string inn) { List<Provider> providers = new List<Provider>(); HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(String.Format("https://zakupki.gov.ru/epz/dishonestsupplier/search/results.html?morphology=on&sortBy=UPDATE_DATE&pageNumber=1&sortDirection=false&recordsPerPage=_10&showLotsInfoHidden=false&fz94=on&fz223=on&ppRf615=on&customerINN={0}", inn)); Request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"; Request.Headers.Add("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"); Request.Headers.Add("TE", "Trailers"); Request.Headers.Add("Cache-Control", "no-cache"); Request.Headers.Add("Pragma", "no-cache"); Request.Headers.Add("Accept-Encoding", "gzip, deflate, br"); Request.Headers.Add("TE", "Trailers"); Request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; Request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; HttpWebResponse Response = (HttpWebResponse)Request.GetResponse(); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.Load(Response.GetResponseStream(), Encoding.UTF8); HtmlNodeCollection divs = doc.DocumentNode.SelectNodes("//div[@class='row no-gutters registry-entry__form mr-0']");/*[0].SelectNodes(".//a[@class='bloko-link']");*/ if (divs == null) return providers; foreach (HtmlNode div in divs) { Provider provider = new Provider(); HtmlNodeCollection blocks = divs[0].SelectNodes("//div[@class='registry-entry__body-block']"); foreach (HtmlNode htmlNode in blocks) { List<HtmlNode> childDiv = htmlNode.ChildNodes.Where(r => r.Name == "div").ToList(); switch (childDiv[0].InnerText.Trim().Replace("\n", "")) { case "ИНН (аналог ИНН)": provider.INN = childDiv[1].InnerText; continue; case "Страна": provider.Country = childDiv[1].InnerText; continue; case "Наименование (ФИО) недобросовестной подрядной организации": case "Наименование (ФИО) недобросовестного поставщика": provider.Name = childDiv[1].InnerText.Replace("\n", "").Replace("\t", "").Replace("\r", "").Replace(" ", ""); continue; default: string a = childDiv[0].InnerText.Trim().Replace("\n", ""); continue; } } if (inn != provider.INN) { continue; } provider.SomethingNum = divs[0].SelectNodes(".//div[@class='registry-entry__header-mid__number']")[0].InnerText.Trim(); provider.Url = divs[0].SelectNodes(".//div[@class='registry-entry__header-mid__number']")[0].SelectNodes(".//a")[0].Attributes["href"].Value; provider.FZ = divs[0].SelectNodes(".//div[@class='registry-entry__header-top__title text-truncate']")[0].InnerText.Replace("\n", "").Replace("\t", "").Replace("\r", "").Trim(); HtmlNode DataBlock = divs[0].SelectNodes(".//div[@class='col d-flex flex-column registry-entry__right-block b-left ']")[0]; HtmlNodeCollection DataBlocks = DataBlock.SelectNodes(".//div[@class='data-block__value']"); if (DataBlocks.Count < 4) { List<DateTime> dates = new List<DateTime>(); foreach (HtmlNode htmlNode in DataBlocks) { if (htmlNode.ParentNode.Attributes["class"].Value == "col-6") dates.Add(Convert.ToDateTime(htmlNode.InnerText)); } dates = dates.OrderBy(r => r).ToList(); provider.DateAdd = dates[0]; provider.DateUpdate = dates[1]; HtmlNode end = DataBlocks.Where(r => r.ParentNode.Attributes["class"].Value != "col-6").FirstOrDefault(); if (end != null) { provider.DateEnd = Convert.ToDateTime(end.InnerText); } } else { string a = ""; }; providers.Add(provider); } return providers; } }
Далее используем эту функцию на списке ИНН:
List<Provider> providers = new List<Provider>(); foreach(string inn in INNs) { providers = providers.Concat(Metods.GetProviderFromSite(inn)).ToList(); } providers.Write();
Таким образом, у меня получилось собрать информацию об интересующих контрагентах. От себя хотелось бы добавить, что сайт имеет особенность: по тем ИНН, где информацию получить не удалось, попробуйте запустить скрипт еще раз: есть шанс, что найдется информация по ним.
