<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Автоматизируем SEO-анализ конкурентов с Puppeteer, Zod и TypeScript: DIY-скрипт]]></title><description><![CDATA[<p dir="auto"><img src="/assets/uploads/files/d2/20/fb/1773912765902-generated_1773912720642-resized.webp" alt="Обложка: Как автоматизировать SEO-анализ конкурентов с Puppeteer, Zod и TypeScript: DIY-скрипт для Node.js" class=" img-fluid img-markdown" /></p>
<p dir="auto">SEO-анализ конкурентов руками - это ад. Залипаешь часами в Ahrefs или Serpstat, копируешь титлы, мета, ключевики, а толку ноль - данные устаревают за день. Этот скрипт на Puppeteer, Zod и TypeScript парсит всё автоматически: сниппеты, заголовки, ссылки конкурентов прямо из выдачи. Запускаешь на Node.js - и получаешь чистый JSON для дальнейшей обработки или ИИ-анализа.</p>
<p dir="auto">Зачем это нужно? Экономит 80% времени, даёт свежие данные без платных API, масштабируется на сотни запросов. Идеально для пет-проектов или когда бюджет на инструменты жмёт. Плюс, с Zod типизируем вывод - никаких сюрпризов в данных.</p>
<h2>Почему Puppeteer - король для SEO-парсинга</h2>
<p dir="auto">Puppeteer рендерит JavaScript как настоящий браузер, так что SPA-конкуренты с динамикой не проблема. Headless-режим скрывает автоматизацию, обходит базовые антиботы. В отличие от Cheerio, который жрёт статический HTML, тут полная эмуляция: скролл, клики, ожидание загрузки. Реальный кейс: парсим топ-10 Яндекса по “купить iPhone” - титлы, описания, URL улетают в базу за минуты.</p>
<p dir="auto">С TypeScript добавляем строгую типизацию - скрипт не сломается на кривых данных. Zod валидирует парсинг: если сниппет не влез - ошибка сразу. Без этого хаос: один домен вернёт 404, другой заблокирует - и весь массив в мусор. Плюс, легко интегрировать с ИИ: кидаешь JSON в GPT для кластеризации ключей.</p>
<p dir="auto">Вот ключевые плюсы стека:</p>
<ul>
<li><strong>Puppeteer</strong>: Обходит JS-рендер, имитирует юзера - стабильность 95%+.</li>
<li><strong>Zod</strong>: Схемы валидации - данные всегда типизированы, без ручных чеков.</li>
<li><strong>TypeScript</strong>: Автокомплит, рефакторинг - код как конструктор Lego.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Инструмент</th>
<th>Плюсы</th>
<th>Минусы</th>
</tr>
</thead>
<tbody>
<tr>
<td>Puppeteer</td>
<td>JS-рендер, DevTools</td>
<td>Жрёт RAM (200-500 МБ/страница)</td>
</tr>
<tr>
<td>Cheerio</td>
<td>Лёгкий, быстрый</td>
<td>Нет динамики</td>
</tr>
<tr>
<td>Playwright</td>
<td>Мультибраузер</td>
<td>Круче, но heavier</td>
</tr>
</tbody>
</table>
<h2>Установка и настройка: 5 минут до первого парса</h2>
<p dir="auto">Сначала ставим зависимости: puppeteer для браузера, zod для схем, typescript и ts-node для запуска. npm i -D @types/node ts-node. Всё на Node.js 20+. Скачивается Chromium автоматически - не паримся с драйверами. Конфигим userAgent на реальный Chrome, добавляем прокси если Яндекс злой.</p>
<p dir="auto">В package.json скрипты: “dev”: “ts-node scraper.ts”. Запуск - node dist/scraper.js после tsc. Логируем в файл, чтобы не засорять консоль. Тестируем на одном запросе: “seo анализ” - и вуаля, JSON с 10 конкурентами. Масштаб: очередь на 100+ запросов с лимитом 1/sec, чтоб не банили.</p>
<p dir="auto">Шаги установки:</p>
<ul>
<li><code>npm init -y &amp;&amp; npm i puppeteer zod &amp;&amp; npm i -D typescript @types/node ts-node</code></li>
<li>Создай tsconfig.json: {“compilerOptions”: {“target”: “ES2020”, “module”: “commonjs”, “strict”: true}}</li>
<li><em>UserAgent ротируй вручную или через puppeteer-extra-plugin</em>.</li>
</ul>
<pre><code class="language-typescript">// tsconfig.json фрагмент
{"include": ["src/**/*"], "ts-node": {"esm": false}}
</code></pre>
<h2>Основной скрипт: парсим выдачу конкурентов</h2>
<p dir="auto">Код делим на функции: launchBrowser, searchQuery, extractSnippet. Идём на <a href="http://google.com" target="_blank" rel="noopener noreferrer">google.com</a> или <a href="http://yandex.ru" target="_blank" rel="noopener noreferrer">yandex.ru</a>, вбиваем запрос через page.type, ждём результаты. Puppeteer.click на пагинацию если нужно топ-50. Извлекаем селекторы: h3 для титлов, .snippet для описаний, a[href] для URL. Zod схема проверяет: title.length &gt; 10, url.startsWith(‘http’).</p>
<p dir="auto">Обработка ошибок: если captcha - retry с новым прокси. Параллелим запросы Promise.all, но не больше 5 одновременно. Выводим в файл или Mongo. Пример: по запросу “node.js курсы” хватит 3 страницы - 30 конкурентов с метриками.</p>
<p dir="auto">Ключевые селекторы для Яндекса/Google:</p>
<ul>
<li><strong>Титлы</strong>: ‘h3[data-lines]’ или ‘. OrganicTitle’</li>
<li><strong>Описания</strong>: ‘.organic__url-text’ / ‘div[data-sncf]’</li>
<li><strong>URL</strong>: ‘a[href].serp-item__title-link’</li>
</ul>
<p dir="auto">Полный скрипт ниже - копипасть и лети:</p>
<pre><code class="language-typescript">import puppeteer from 'puppeteer';
import { z } from 'zod';

type Competitor = {
  title: string;
  description: string;
  url: string;
};

const CompetitorSchema = z.object({
  title: z.string().min(1),
  description: z.string().optional(),
  url: z.string().url()
});

const parseCompetitors = async (query: string): Promise&lt;Competitor[]&gt; =&gt; {
  const browser = await puppeteer.launch({ headless: 'new' });
  const page = await browser.newPage();
  await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
  await page.goto(`https://yandex.ru/search/?text=${encodeURIComponent(query)}`, { waitUntil: 'networkidle0' });

  const competitors: Competitor[] = await page.evaluate(() =&gt; {
    return Array.from(document.querySelectorAll('li.serp-item')).map(el =&gt; {
      const titleEl = el.querySelector('h2 a') as HTMLElement;
      const descEl = el.querySelector('.organic__text') as HTMLElement;
      const linkEl = el.querySelector('h2 a') as HTMLAnchorElement;
      return {
        title: titleEl?.innerText || '',
        description: descEl?.innerText || '',
        url: linkEl?.href || ''
      };
    }).slice(0, 10);
  });

  await browser.close();
  return z.array(CompetitorSchema).parse(competitors);
};

// Использование
(async () =&gt; {
  const data = await parseCompetitors('seo анализ конкурентов');
  console.log(JSON.stringify(data, null, 2));
})();
</code></pre>
<p dir="auto"><em>Нюанс: для Google меняй селекторы на g-search-item или используй SerpAPI если паранойя</em>.</p>
<h2>Расширение: ИИ-анализ и экспорт данных</h2>
<p dir="auto">Собранный JSON кидай в OpenAI API: кластеризуй ключи, оцени контент по LSI. Zod обеспечит чистый ввод. Добавь экспорт в CSV/Excel via papaparse. Мониторинг: cron на серваке раз в день парсит топ-5 ниш, сравнивает видимость.</p>
<p dir="auto">Интеграция простая: после парса POST в /analyze с промптом. Пример: “Проанализируй эти титлы конкурентов и предложи улучшения”. Масштаб до 1000 запросов/день с ротацией IP. Сравни с платными: бесплатно, кастомно, без лимитов.</p>
<p dir="auto">Возможности расширения:</p>
<ul>
<li><strong>ИИ-кластеризация</strong>: GPT-4o по JSON генерит топики.</li>
<li><strong>Ссылка-парсинг</strong>: Качай robots.txt, sitemap.xml.</li>
<li><strong>Мониторинг</strong>: Сохраняй в Supabase, алерты на изменения.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Фича</th>
<th>Время на имплемент</th>
<th>Польза</th>
</tr>
</thead>
<tbody>
<tr>
<td>ИИ-анализ</td>
<td>30 мин</td>
<td>Кластеры ключей</td>
</tr>
<tr>
<td>Экспорт CSV</td>
<td>10 мин</td>
<td>Отчёты в Google Sheets</td>
</tr>
<tr>
<td>Прокси-ротация</td>
<td>1 час</td>
<td>Антибан</td>
</tr>
</tbody>
</table>
<h2>Скрипт в продакшене: от пет-проекта к рутине</h2>
<p dir="auto">Задеплой на Vercel или Render - serverless функции по запросу. Docker для локалки: Chrome stable + puppeteer. Тестируй на staging: 50 запросов без крашей. Лайфхак: stealth-плагин puppeteer-extra маскирует под человека. Reddit шепчет, что в 2026 Yandex усилил ботов - ротация UA must-have.</p>
<p dir="auto">Бонус: добавь скриншоты топ-страниц via page.screenshot. Храни в S3, анализируй визуал ИИ. Теперь у тебя дашборд: графики позиций, дельта ключей. Экономия - 10 часов/неделю на ручной труд.</p>
<p dir="auto">Масштабирование работает так:</p>
<ul>
<li>1 запрос: 5 сек.</li>
<li>100 запросов: 10 мин с параллелью.</li>
<li><em>Лимит: 2-3 запроса/мин на IP.</em></li>
</ul>
<h2>Когда скрипт покажет зубы</h2>
<p dir="auto">Этот DIY-скрипт бьёт платные сервисы по свежести - парсит live-выдачу без кэша. Осталось доработать: геотаргетинг, мобильная выдача, интеграцию с GA4. Подумай о комбо с LangChain - агент сам решит, какие ключи копать глубже. Технологии рулят, когда экономят часы и нервы.</p>
]]></description><link>https://forum.exlends.ru/topic/1754/avtomatiziruem-seo-analiz-konkurentov-s-puppeteer-zod-i-typescript-diy-skript</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 03:59:47 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/1754.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 19 Mar 2026 09:32:46 GMT</pubDate><ttl>60</ttl></channel></rss>