В одной из задач на улучшение А-Парсера было пожелание сделать В A-Parser есть SE::Yandex::Catalog, но им такую задачу не решить. Поэтому нужно сделать кастомный парсер, который будет парсить любую рубрику/категорию/подкатегорию полностью. В Яндекс.Каталоге есть один нюанс - в одной категории максимум отдается 100 страниц по 10 результатов, т.е. 1000 сайтов. Поэтому единственный вариант спарсить максимум - это спуститься в каждую подкатегорию относительно начального запроса, и там собрать все сайты. Как показывает практика - это дает значительно больше результатов, зачастую даже все. Если проанализировать рубрики/категории в Каталоге, то мы увидим, что работать по такому алгоритму довольно просто. Например, посмотрим на рубрику СМИ (т.е. это наш начальный запрос, верхняя категория): Мы видим, что здесь жирным шрифтом выделены подкатегории, и обычным - подподкатегории. Если перейти в какую-либо подкатегорию, то открывается полный список подподкатегорий (которые уже тоже выделены жирным), и так далее, пока в какой-то подпод...категории больше не будет дочерних элементов (назовем ее нижней категорией). И вот, в каждой такой нижней категории есть свой перечень результатов. Как правило - он не большой, и это позволит нам спарсить значительно больше результатов, чем если бы мы парсили одну главную категорию/рубрику (напомню - там максимум 1000 результатов). Итак, приступим к составлению пресета. Как обычно, используем парсер Net::HTTP. Первым делом парсим список подкатегорий. Для этого используем функцию Parse custom result и регулярное выражение. В Общем формате результата с помощью Template Toolkit прописываем условие, которое будет проверять наличие подкатегорий и если они есть - подставлять их в запросы с помощью tools.query.add; а если нету - будет выводить список сайтов. Спойлер: Условие Код: [% IF p1.cats.size > 0; FOREACH p1.cats; tools.query.add('https://yandex.ru' _ cat); END; ELSE; p1.serp.format('$link ($tic) - $anchor\n'); END %] Для того, чтобы данный код работал, нужно добавить парсинг списка сайтов в пресете с помощью тех же регулярных выражений. Но в таком виде мы получим только по первой странице из каждой нижней категории. Список сайтов выводится постранично (есть пагинация) и нам, чтобы получить все сайты, нужно их "листать". Для этого логично использовать специальную функцию Check next page, но в данном случае это не так. Точнее ее можно использовать, но будет выполнятся лишняя работа, т.к. будут "листаться" все подкатегории. А нам достаточно только нижних. Поэтому нужно вручную подставлять ссылку на следующую страницу в запросы. И только тогда, когда обрабатывается нижняя категория. Для этого одновременно с выводом списка сайтов добавим переход на следующую страницу. Соответственно, в пресете нужно парсить регуляркой ссылку на нее. Таким образом полный шаблон результата будет выглядеть так: Код: [% IF p1.cats.size > 0; FOREACH p1.cats; tools.query.add('https://yandex.ru' _ cat); END; ELSE; p1.serp.format('$link ($tic) - $anchor\n'); IF p1.np != 'none'; tools.query.add('https://yandex.ru' _ p1.np); END; END %] Добавляем в пресет Check RegEx для проверки каптчи (чтобы парсер повторял запрос, если будет получена каптча) и включаем уникализацию результатов (т.к. сайты дублируются в разных категориях, а в результате врятли нужны дубли). В итоге полностью пресет будет выглядеть так: Спойлер: Код для импорта Код: eyJwcmVzZXQiOiJZYUNhdGFsb2ciLCJ2YWx1ZSI6eyJwcmVzZXQiOiJZYUNhdGFs b2ciLCJwYXJzZXJzIjpbWyJOZXQ6OkhUVFAiLCJkZWZhdWx0Iix7InR5cGUiOiJv dmVycmlkZSIsImlkIjoiZ29vZENvZGUiLCJ2YWx1ZSI6WzIwMF19LHsidHlwZSI6 Im9wdGlvbnMiLCJpZCI6ImNoZWNrQ29udGVudCIsInZhbHVlIjoiPGgxIGNsYXNz PVwidGl0bGVcIj5cdTA0M2VcdTA0MzkuLi48L2gxPiIsImFkZGl0aW9uYWwiOnsi Y2hlY2tDb250ZW50TWF0Y2hUeXBlIjowfX0seyJ0eXBlIjoiY3VzdG9tUmVzdWx0 IiwicmVzdWx0IjoiZGF0YSIsInJlZ2V4IjoiPGgzIGNsYXNzPVwiY2F0ZWdvcnlf X3RpdGxlXCI+PGEuKz9ocmVmPVwiKC4rPylcIiIsInJlZ2V4VHlwZSI6ImciLCJy ZXN1bHRUeXBlIjoiYXJyYXkiLCJhcnJheU5hbWUiOiJjYXRzIiwicmVzdWx0cyI6 WyJjYXQiXX0seyJ0eXBlIjoiY3VzdG9tUmVzdWx0IiwicmVzdWx0IjoiZGF0YSIs InJlZ2V4IjoiPGJ1dHRvbiBjbGFzcz1cImJ1dHRvbiBidXR0b25fdGhlbWVfaXNs YW5kcyBidXR0b25fc2l6ZV9tIGJ1dHRvbl9jaGVja2VkIHBhZ2VyX19wYWdlIGJ1 dHRvbl9fY29udHJvbCBpLWJlbVwiW14+XSo+PHNwYW4gY2xhc3M9XCJidXR0b25f X3RleHRcIj5cXGQrPFxcL3NwYW4+PFxcL2J1dHRvbj48YVtePl0raHJlZj1cIihb XlwiXSspW1wiP10iLCJyZWdleFR5cGUiOiIiLCJyZXN1bHRUeXBlIjoiZmxhdCIs ImFycmF5TmFtZSI6IiIsInJlc3VsdHMiOlsibnAiXX0seyJ0eXBlIjoiY3VzdG9t UmVzdWx0IiwicmVzdWx0IjoiZGF0YSIsInJlZ2V4IjoiPGxpIGNsYXNzPVwieWFj YS1zbmlwcGV0XCI+KC4rPyk8XFwvbGk+IiwicmVnZXhUeXBlIjoic2ciLCJyZXN1 bHRUeXBlIjoiYXJyYXkiLCJhcnJheU5hbWUiOiJzZXJwZGF0YSIsInJlc3VsdHMi OlsiZGF0YSJdfSx7InR5cGUiOiJjdXN0b21SZXN1bHQiLCJyZXN1bHQiOlsic2Vy cGRhdGEiLCJkYXRhIl0sInJlZ2V4IjoiPGgyIGNsYXNzPVwieWFjYS1zbmlwcGV0 X190aXRsZVwiPjxhLis/aHJlZj1cIiguKz8pXCIuKz8+KC4rPyk8XFwvYT4uKz88 ZGl2IGNsYXNzPVwieWFjYS1zbmlwcGV0X19jeVwiPlx1MDQyMlx1MDQxOFx1MDQy NjogKFxcZCspIiwicmVnZXhUeXBlIjoiIiwicmVzdWx0VHlwZSI6ImFycmF5Iiwi YXJyYXlOYW1lIjoic2VycCIsInJlc3VsdHMiOlsibGluayIsImFuY2hvciIsInRp YyJdfV1dLCJyZXN1bHRzRm9ybWF0IjoiWyUgSUYgcDEuY2F0cy5zaXplID4gMDtc blx0Rk9SRUFDSCBwMS5jYXRzO1xuXHRcdHRvb2xzLnF1ZXJ5LmFkZCgnaHR0cHM6 Ly95YW5kZXgucnUnIF8gY2F0KTtcblx0RU5EO1xuRUxTRTtcblx0cDEuc2VycC5m b3JtYXQoJyRsaW5rICgkdGljKSAtICRhbmNob3JcXG4nKTtcblx0SUYgcDEubnAg IT0gJ25vbmUnO1xuXHRcdHRvb2xzLnF1ZXJ5LmFkZCgnaHR0cHM6Ly95YW5kZXgu cnUnIF8gcDEubnApO1xuXHRFTkQ7XG5FTkQgJV0iLCJyZXN1bHRzU2F2ZVRvIjoi ZmlsZSIsInJlc3VsdHNGaWxlTmFtZSI6IiRkYXRlZmlsZS5mb3JtYXQoKS50eHQi LCJhZGRpdGlvbmFsRm9ybWF0cyI6W10sInJlc3VsdHNVbmlxdWUiOiJzdHJpbmci LCJxdWVyeUZvcm1hdCI6WyIkcXVlcnkiXSwidW5pcXVlUXVlcmllcyI6ZmFsc2Us InNhdmVGYWlsZWRRdWVyaWVzIjpmYWxzZSwiaXRlcmF0b3JPcHRpb25zIjp7Im9u QWxsTGV2ZWxzIjpmYWxzZSwicXVlcnlCdWlsZGVyc0FmdGVySXRlcmF0b3IiOmZh bHNlLCJxdWVyeUJ1aWxkZXJzT25BbGxMZXZlbHMiOmZhbHNlfSwicmVzdWx0c09w dGlvbnMiOnsib3ZlcndyaXRlIjpmYWxzZX0sImRvTG9nIjoibm8iLCJrZWVwVW5p cXVlIjoiTm8iLCJtb3JlT3B0aW9ucyI6ZmFsc2UsInJlc3VsdHNQcmVwZW5kIjoi IiwicmVzdWx0c0FwcGVuZCI6IiIsInF1ZXJ5QnVpbGRlcnMiOltdLCJyZXN1bHRz QnVpbGRlcnMiOlt7InNvdXJjZSI6WzAsWyJzZXJwIiwiYW5jaG9yIl1dLCJ0eXBl IjoiZGVjb2RlSHRtbCIsImFycmF5Ijoic2VycCIsInRvIjoiYW5jaG9yIn1dLCJj b25maWdPdmVycmlkZXMiOltdLCJydW5UYXNrT25Db21wbGV0ZSI6bnVsbCwidXNl UmVzdWx0c0ZpbGVBc1F1ZXJpZXNGaWxlIjpmYWxzZSwicnVuVGFza09uQ29tcGxl dGVDb25maWciOiJkZWZhdWx0IiwidG9vbHNKUyI6IiJ9fQ== На вход можно подавать ссылку на любую категорию, рубрику или регион Я.Каталога в любых сочетаниях. Например: В данном пресете результат будет выглядеть так: