Набор Python-скриптов для автоматизации рутинных задач SEO-специалиста
Статья будет полезна специалистам, которые хотели бы автоматизировать свою работу. Для работы со скриптами потребуются минимальные знания программирования и установленные библиотеки. Для каждого примера в конце есть ссылка на полный код, который нужно открывать в Jupyter Notebook. Больше скриптов в Telegram-канале seo_python.
С каждым годом процесс оптимизации требует всё больше технических навыков. Среди текущих требований к специалисту часто указывают, что необходимо знание какого-либо языка программирования, например, Python.
Python — простой и лаконичный язык, позволяющий автоматизировать значительную часть рутинных задач и анализировать данные, что особенно актуально при работе с крупными проектами.
Одно из преимуществ языка — наличие большого количества написанных библиотек. Так как многие сервисы отдают свои данные по API, у специалистов есть возможность без глубоких знаний программирования писать скрипты для решения рабочих задач.
В западных блогах часто можно встретить подборки специалистов, которые делятся своими наработками. В рунете такой информации пока мало, поэтому в этой статье я бы хотел рассказать о полезных библиотеках и поделиться своим набором скриптов, которые постоянно использую в работе.
1. Генерация RSS-фида для турбо-страниц «Яндекса»
Этот способ подходит для случаев, когда необходимо быстро запустить и протестировать турбо-страницы. Рекомендую использовать скрипт для генерации RSS-канала для статейных сайтов, контент которых изменяется редко. Этот метод подходит для быстрого запуска страниц с целью проверить теорию и посмотреть результаты внедрения технологии «Яндекса».
Что потребуется:
- Netpeak Spider.
- Базовые знания применения XPath.
- Установленные Python-библиотеки.
Плюсы подхода:
- Быстрое внедрение. Не требуется помощь программиста.
- Не нужно подключение к базе, где хранится контент. Весь контент и его разметку берём прямо со страниц (одновременно минус).
- Используем стандартные SEO-инструменты.
Минусы:
- Необновляемый XML-файл. После изменения контента требуется пересобрать контент и формировать новый XML.
- Новые страницы также не будут попадать в файл. Для них будет необходимо заново парсить контент и формировать XML.
- Создаём нагрузку на свой сайт при сборе контента.
Ниже описана последовательность работ.
Подготавливаем данные
С помощью Screaming frog seo spider или Netpeak Spider парсим контент страниц, для которых будем подключать турбо-страницы.
На этом этапе подготавливаем данные для обязательных элементов, необходимых при формировании XML-файла.
Обязательные поля:
- Link — URL страницы.
- H1 — заголовок страницы.
- Turbo:content — содержимое страницы.
Подробнее — на странице.
Используя XPath, парсим контент страниц со всей HTML-разметкой. Копируем через панель разработчика или пишем свой запрос (например, //div[@class='entry-content entry--item']).
Экспортируем полученные данные в CSV. В результате в CSV-файле должно быть три столбца:
- Link.
- H1.
- Turbo:content.
Скрипт генерации файла
Подключаем нужные библиотеки.
Считываем файл с подготовленными данными.
Выводим информацию о количестве строк в файле и итоговом количестве RSS-файлов, которые будут сгенерированы.
Формируем структуру RSS-канала. Создаём функцию create_xml, отвечающую за создание начала файла.
Функция close_xml будет закрывать файл.
В функцию data_for_rss передаём номер первой и последней строки. Для этого промежутка будем формировать RSS.
Построчно считываем строки в датафрейме и формируем <item>, записывая получившиеся данные в XML-файл. Каждая строка в датафрейме — новая страница.
Делаем проверку размера получившихся фидов. Размер XML-файла не должен превышать 15 МБ. Если размер получился больше, изменяем количество строк в одном файле, изменяя значение переменной rows_in_rss.
Финальный шаг — генерация фидов.
Остаётся добавить RSS в личном кабинете «Яндекс.Вебмастера» и настроить меню, лого, счётчики систем аналитики.
Ссылка на скрипт (открывать в Jupyter Notebook).
2. Техническое задание для копирайтеров
ТЗ для копирайтеров — довольно рутинная работа, которая занимает много времени у специалиста. Ниже рассмотрим три варианта автоматизации этого процесса, используя различные сервисы:
- Семантического ядра нет, статья не написана.
- Семантическое ядро есть, статья не написана.
- Статья написана, требуется рерайт.
Что потребуется:
Ниже рассмотрим все варианты, для каждого я распишу плюсы и минусы этих подходов. Стоит помнить, что результаты, которые выдают сервисы, стоит перепроверять. Так как везде есть свои технические нюансы.
Вариант 1. Семантического ядра нет, статья не написана
Рассмотрим случай, когда нужно написать статью, но у вас нет готового семантического ядра. Для этого подхода нам понадобится только основной маркерный запрос статьи.
Плюсы подхода:
- Не тратим время на сбор ядра (подходит для статей с широкой семантикой и хорошей видимостью URL конкурентов в топе).
- В работу берём максимальное количество ключей, по которым конкуренты имеют видимость.
Минусы:
- Нужна подписка на сервисы.
- Данные, которые выдают сервисы, не всегда точны. Например, Megaindex не определяет длину текста меньше определённого количества знаков (около 200 символов). Поэтому показатели выборочно стоит перепроверить.
- Не можем повлиять на кластеризацию.
Подключаем необходимые библиотеки.
Нам понадобятся:
- Token — токен API MegaIndex.
- Ser_id — регион, по которому будут сниматься данные. Полный список можно получить, используя метод get_ser.
- Keywords_list — список ключевых слов, для которых будем получать данные.
Для получения ключевых слов по нужным нам маркерным запросам будем использовать метод url_keywords API Serpstat. Этот метод возвращает ключевые фразы в топе поисковой системы по заданному URL. Получать будем видимость конкурентов по URL, которые находятся в топе выбранной поисковой системы.
Для работы берём пример кода из документации и оборачиваем его в функцию serpstat_keywords. Подставляем свои значения для token и региона se, по которому будем получать данные. Получить полный список регионов можно здесь.
Используя регулярное выражение, разбиваем исходную фразу на слова. Каждое слово лемматизируем, проверяем на часть речи и добавляем в результирующий список. Возвращаем готовый список.
Не забываем, что pymorphy2 работает только с русским языком. Если в словосочетаниях будут фразы на другом языке, он их пропустит.
Составляем словарь вида «Лемма: [количество упоминаний леммы]».
Создаём финальный файл и записываем строку заголовка.
Получаем данные по API и парсим полученный текст.
Проходимся по списку маркерных запросов и генерируем задание.
Получившийся результат переносим в «Google Таблицы». Пример ТЗ.
Нужно понимать, что «количество упоминаний леммы» в ТЗ — это сколько раз лемма встречалась в ключевых словах.
Ссылка на скрипт (открывать в Jupyter Notebook).
Вариант 2. Статья написана, требуется рерайт
Подход применим для случаев, когда статья уже написана, но не получает трафика.
Плюсы подхода:
- В автоматическом режиме получаем средний объём текста в топ-10, объём анализируемого текста и разницу этих величин.
- В работу берём максимальное количество ключей, по которым конкуренты имеют видимость.
Минусы (те же, что и у варианта номер один):
- Нужна подписка на сервисы.
- Данные, которые выдают сервисы, не всегда точны. Например, Megaindex не определяет длину текста меньше определённого количества знаков (около 200 символов). Поэтому показатели выборочно стоит перепроверить.
- Не можем повлиять на кластеризацию.
Набор библиотек аналогичен варианту номер один, отличается набор входных параметров. Вместо списка основных маркерных запросов передаём словарь следующего вида:
{'основной маркерный запрос статьи №1':'url, соответствующий основному маркерному запросу'}
Следующие функции копируем из первого варианта:
- serpstat_keywords;
- morph_word_lemma;
- counter_dict_list.
Чистим файл и записываем строку заголовка.
Получаем данные по API и парсим полученный текст. Получать будем следующие данные для ТЗ:
- list_base_urls — список URL в топ-10 по маркерному запросу;
- relevance — релевантность анализируемой страницы страницам в топе;
- symbols_median — медиана длины текста (знаков без пробелов) по топу;
- symbols_text — количество символов в анализируемом тексте;
- symbols_diff — разница symbols_median и symbols_text;
- words_median — медиана слова в URL по топу;
- words_value_text — медиана слов в анализируемом тексте;
- words_diff — разница слов;
- count_lemma— посчитанные леммы.
Проходимся по списку маркерных запросов и генерируем задание.
Ссылка на скрипт (открывать в Jupyter Notebook).
Вариант 3. Семантическое ядро есть, статья не написана
Рассмотрим ситуацию, когда у специалиста есть собранное и кластеризованное семантическое ядро.
Плюсы подхода:
- Работаем уже с тщательно проработанным и кластеризованным семантическим ядром.
Минусы (почти те же, что и у первого варианта):
- Нужна подписка на сервисы.
- Данные, которые выдают сервисы, не всегда точны. Например, Megaindex не определяет длину текста меньше определённого количества знаков (около 200 символов). Поэтому показатели выборочно стоит перепроверить.
Подключаем необходимые библиотеки, указываем токен для работы с Megaindex и ser_id нужного региона.
Для работы скрипта нам понадобится txt-файл ('data_tz.txt') с кластеризованным ядром.
Формат файла: Ключ → Группа; разделитель табуляция.
Работаем со словарём, полученным на предыдущем шаге. Для каждой группы обходим все ключевые фразы, разбиваем их на слова, нормализуем и добавляем в словарь.
Получаем данные по API и парсим полученный текст.
Подготавливаем финальный файл.
Проходимся по списку групп и генерируем задание.
Так как основной маркерный запрос в этом случае — название категории, нужно следить за полнотой и правильностью её написания.
Аналогично первому варианту, получившийся результат переносим в «Google Таблицы». Получившееся ТЗ в таком же формате.
Ссылка на скрипт (открывать в Jupyter Notebook).
Предложенные скрипты можно дорабатывать, добавляя в них и другие важные на ваш взгляд требования к тексту.
Имея список URL конкурентов, можно парсить:
- Title страниц.
- Заголовки H1 — H6.
- Количество нумерованных, маркированных списков, изображений на странице и так далее.
Аналогичным способом делать морфологический анализ тегов, заголовков и выдавать рекомендации по количеству элементов и упоминаний лемм в этих тегах.
3. Анализ логов
При техническом аудите сайтов полезно анализировать логи сайта. Возможные варианты анализа:
- Использовать возможности, которые предоставляет хостер. Чаще всего это решение в виде надстройки, например, AWStats. Минусы: не гибко, чаще всего предоставляется определённый набор графиков, которые никак не изменить.
- Использовать платные решения. Например, Screaming Frog SEO Log File Analyser — бесплатная версия работает с файлами до 1000 строк. Минусы: цена, не всегда логи вашего сервера будут соответствовать тому виду, который требуется для работы в программе.
- Использовать ELK-стек (elastic + logstash + kibana). Минусы: требуются знания по настройке хранилища и передаче в него данных.
- Решение на Python с использованием библиотек.
Подробнее что про то, что такое логи, их структуру и содержание можно почитать в статье. Перейдём к скрипту.
Что потребуется:
- Лог-файлы сайта.
- Установленные Python-библиотеки.
Плюсы подхода:
- Бесплатное решение.
- Можно быстро проанализировать лог-файл в любом формате.
- Легко обрабатывает большие файлы на несколько миллионов записей.
Минусы:
- Хранение данных на своём устройстве (если работаете не на выделенном сервере).
- Чтобы проанализировать данные за новый период, необходимо заново считать данные, разобрать и записать их в анализируемый CSV-файл.
- В приведённом скрипте только базовые универсальные примеры анализа.
Для работы будем использовать библиотеку apache-log-parser, подробная документация по ссылке на GitHub.
Для начала обработаем наш лог-файл и запишем данные в CSV. Если файлов несколько, склеить их можно следующей командой:
!cat access.log.1 access.log.2 access.log.3 > all_log.log
Создаем файл log.csv и записываем в него строку заголовка с названием столбцов. Столбцы определяются в соответствии с вашим лог-файлом.
Читаем построчно access.log, парсим строку и записываем разобранные данные в CSV. Используем функцию make_parser, которая принимает строку из файла журнала в указанном нами формате и возвращает проанализированные значения в виде словаря.
Формат строки из журнала указывается в make_parserс помощью поддерживаемых значений, указанных в документации, — supported values.
Пример строки
54.36.148.252 example.ru — [13/Oct/2019:12:00:01 +0300] "GET /lenta/example/example/p1 HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)" 0.137 0.137 .
Пример разбора
Далее анализируем полученный CSV-файл. Анализ можно провести в Excel или любом другом удобном инструменте. Для примера рассмотрим несколько вариантом получения данных на Python.
Подключаем библиотеку для анализа данных и считываем файл.
Посмотрим распределение страниц по статус коду страниц.
Посчитаем количество страниц со статусом 410 для каждого user-agent.
В результате работы скрипта мы получили готовый CSV-файл с разобранными по столбцам записями из лог-файла. Далее можно анализировать данные в соответствии с вашими целями.
Ссылка на скрипт (открывать в Jupyter Notebook).
Больше автоматизации!! Еще и наработки есть?
Да, есть. Но в основном все специфичные, под конкретные задачи, конкретного сайта. В статье описал наиболее универсальные
Более 100 человек посчитали полезным. Менее 20 решили поблагодарить плюсиком. Три человека написали комментарии. Из них 1 по делу, один автор, один я.
Такая себе вороночка)
+ многие пишут сразу в лс, так что в итоге неплохо получается
Кому интересна данная тема, предлагаю присоединиться к каналу https://t.me/seo_python. Туда буду публиковать свои и найденные в интернете скрипты. Если у вас есть наработки, которыми вы готовы поделиться, присылайте мне (@va_medvedev) в телеграм.
не могу поставить +
У меня недавно спрашивали, почему Python вдруг стал таким популярным. Да вот почему.