Как автоматизировать сохранение истории запросов из Search Console
В статье речь пойдет о том, как получать статистику по дням в 1 клик и настроить автоматическое сохранение истории запросов без помощи программиста.
При работе с интерфейсом Search Console есть несколько существенных недостатков, которые сильно замедляют процесс получения, обработки и анализа данных:
- Отсутствие истории запросов более чем за 90 дней
- Проблема с выгрузкой полного объема данных (разовая выгрузка до 1000 запросов)
- Неудобный интерфейс, отсутствие фильтрации по регулярным выражениям
Получить данные о поисковых запросах за последние 90 дней с возможностью их перезаписи и обновления можно при помощи Google Spreadsheets и дополнения Search Analytics for Sheets.
Но при этом мы не видим и не можем получить статистику по дням в 1 клик, а сохранять исторические данные придется вручную.
Решение
Данную проблему можно решить при настройке автоматического запуска R Script. В статье мы рассмотрим:
- Запуск R и R Studio
- Настройка автоматической аутентификации в аккаунт Google.
- Парсинг поисковых запросов при помощи R скрипта
- Дозапись в файл новой статистики по запросам
- Настройка расписания запуска R скрипта
На выходе получаем таблицу с упорядоченным набором данных (Tidy Data). Такие данные легко использовать для анализа и построения BI моделей, которые не требуют дополнительного структурирования.
Запуск R и R Studio
- Для начала нужно скачать и установить R. Скачать R Studio для некоммерческого использования можно бесплатно на официальном сайте.
- После запуска R Studio создаем R Script
- Установка и подключение библиотек.
Пакет googleAuthR используем для аутентификации в Google аккаунт. Пакет searchConsoleR используется для импорта данных и управления проектом в Search Console.
# Установка пакетов install.packages("googleAuthR") install.packages("searchConsoleR") # Подключение библиотек library(googleAuthR) library(searchConsoleR)
Установка прошла успешно:
Запускаем часть кода просто скопировав нужные строки в R Console и нажав Enter:
Автоматическая авторизация в аккаунт Google.
Для того, чтобы впоследствии настроить автоматическое обновление данных из Search Console необходимо настроить Сервисный аккаунт Google и создать файл client_secret.json, который будет использоваться для аутентификации каждый раз при запуске R скрипта.
- Создаем проект в Google Developers Console
- Переходим в “Учетные данные”, а затем в настройки API
- Выбираем из списка Google Search Console API и включаем его:
- Теперь необходимо настроить учетные данные
- Создаем новый сервисный аккаунт:
- Выставляем настройки. Имя сервисного аккаунта может быть любое.
При создании ключа сервисного аккаунта в следующем всплывающем окне выбираем “Создать без роли”.
- После этого появится окно для сохранения файла json. Сохраняем secret json в надежное место. Этот файл в дальнейшем мы будем использовать для авторизации.
- Теперь сервисному аккаунту необходимо открыть полный доступ в панели Search Console.
- Для этого переходим в “Управление сервисным аккаунтом”.
- В настройках включаем полный доступ к аккаунту.
- Далее копируем идентификатор сервисного аккаунта
- Переходим в панель Search Console https://www.google.com/webmasters/tools/user-admin?hl=en&siteUrl=
- Выбираем проект и добавляем нового пользователя с полными правами:
Важно: Для выполнения данного действия необходимо, чтобы у вас были права владельца. Если получить их не получится, необходимо обратиться к пользователю с правами владельца, чтобы добавить указанный идентификатор сервисного аккаунта с полными правами.
На этом внешние настройки закончены переходим в R Studio и добавляем строку:
service_token <- gar_auth_service("C:/Users/путь-к-вашему-service-token.json")
Парсинг и дозапись данных в файл:
- Далее запускаем можем использовать следующий R-Script для парсинга и обновления файла с данными.
# Подключение библиотек library(googleAuthR) library(searchConsoleR) # Авторизация в аккаунт Google service_token <-gar_auth_service("C:/Users/Anastasiya/Documents/R/Docs/service_gsc_1.json") # Пишем дату запуска скрипта в log message(Sys.time(),"\r",appendLF=TRUE) # Указываем название сайта в таком же виде, как он находится в Search Console website <- "https://preply.com/" # Указываем путь расположения файла. Можно сохранять файл прямо к себе на One Drive path <- "C:/Users/Anastasiya/OneDrive/OneDrive - Preply, Inc/csv_data/search-console.csv" # Последняя интересующая нас дата. Обычно -3 дня от текущей end <- Sys.Date() - 3 # Проверяем существует ли уже файл. Таким образом будет выбрано парсить с последней даты в файле или за последние 90 дней. if (file.exists(path)) { # Считываем файл, будем использовать его для добавления новых данных data <- read.table(file=path, sep=",", header=T) data$date <- as.Date(as.character.Date(data$date, format = "%m/%d/%y")) start <- max(data$date) + 1 } else { # Создаем пустую переменную, куда будем парсить данные за 90 дней data <- data.frame() start <- Sys.Date() - 90 } # Устанавливаем русскоязычную кодировку, чтобы видеть русскоязычные запросы в интерфейсе R Studio Sys.setlocale("LC_ALL","russian") # Будем считывать данные по дням в цикле, начиная с первой даты, которую мы задали на предыдущем шаге date <- start # Фиксируем длину начального data frame rows_count <- nrow(data) # Если вдруг дата старта превышает конечную дату, ничего не произойдет. while (date <= end){ data_part <- search_analytics(siteURL = website, startDate = date, endDate = date, dimensions = c('date','page','query','country'), searchType = c('web'), rowLimit = 1000000, walk_data = 'none' ) # Объединяем новые данные с текущими data <- rbind(data,data_part) date <- date + 1 } # Перезаписываем файл, если наш data frame не меньше, чем изначальный if(nrow(data) < rows_count) { message("File hasn't update","\r",appendLF=FALSE) } else { write.csv(data, file = path, row.names=FALSE) }
О функции search_analytics()
Ниже привожу перевод справки создателя пакета searchConsoleR Mark Edmondson:
search_analytics(siteURL, startDate = Sys.Date() - 93, endDate = Sys.Date() - 3, dimensions = NULL, searchType = c("web", "video", "image"), dimensionFilterExp = NULL, aggregationType = c("auto", "byPage", "byProperty"), rowLimit = 1000, prettyNames = TRUE, walk_data = c("byBatch", "byDate", "none") )
Аргументы
siteURL | Имя сайта из Search Console, к которому у вас есть доступ |
startDate | Дата начала требуемого интервала, в YYYY-MM-DD. |
endDate | Дата конца требуемого интервала, в YYYY-MM-DD. |
dimensions | 0 или больше параметров для сегментирования данных (колонки): «date», «country», «device», «page» or «query» |
searchType | Тип поиска, по умолчанию ‘web’. |
dimensionFilterExp | Символьный вектор, который задает фильтр. Пример, («device==TABLET», «country~~GBR») |
aggregationType | Как данные будут агрегированы. |
rowLimit | Сколько строк, максимально 5000. |
walk_data | Для создания вызова API. Один из («byBatch»,»byDate»,»none») |
Детально
startDate, endDate: Оба значения включаются в диапазон.
dimensions: [Не обязательно] Группировка значений параметров объединяются, чтобы создать уникальный ключ для каждой строки результата. Если параметры не указаны, все значения будут объединены в одну строку.
dimensionFilterExp: [Не обязательно] Фильтрация использует следующий синтаксис: («device==TABLET», «country~~GBR», «dimension operator expression«)
dimension
- ‘country’
- ‘device’
- ‘page’
- ‘query’
operator
- ‘~~’ содержит
- ‘==’ равно
- ‘!~’ не содержит
- ‘!=’ не равно
expression
- country: код страны в формате ISO 3166-1 alpha-3 country code.
- device: ‘DESKTOP’,’MOBILE’,’TABLET’.
- page: синтаксис не проверяется, текстовая строка с URL без имени домена.
- query: синтаксис не проверяется, строка с ключевым словом.
searchType: [Не обязательно] Допустимые значения:
- «web»: [По умолчанию] Web search results
- «image»: Image search results
- «video»: Video search results
aggregationType: [Не обязательно]
- «auto»: [По умолчанию] Агрегируются по умолчанию
- «byPage»: Агрегируются по URL.
- «byProperty»: Агрегируются по свойству.
Детальнее можно ознакомится в справке по Search Console API
walk_data: Постепенный вызов запросов с помощью multiple API calls
- byBatch — вызов постепенно (до 5000 строк)
- byData — по дням
- none — разовый вызов
Комментарий:
По моему опыту параметры byBatch и byData не всегда выдают максимально полные данные. Поэтому я выбираю ‘none’ и слежу за полнотой данных вручную. Для получения более полных данных можно сделать следующее:
- уменьшить количество параметров для сегментирования данных
- воспользоваться фильтрами и вызвать функцию с разными фильтрами в рамках цикла.
Как проверить полноту данных:
Обращаем внимание на следующее:
- Количество строк, полученное из одного запроса. Количество строк должно быть значительно ниже, чем возможны предел. (Например, для вызова без параметров, это 5000 строк, а для вызова с 4 параметрами по моему опыту около 1000-1500)
- Визуальный анализ данных по количеству показов и кликов:
Если данные о кликах и показах в рамках одной даты обрезает до 2, или кликов со значением 0 не присутствует вообще, то данные не полные.
Настройка расписания запуска R скрипта:
Данный пакет использует Windows Task Scheduler.
- Устанавливаем пакет “taskscheduleR”
library(devtools) install.packages("devtools") install_github("jwijffels/taskscheduleR") library(taskscheduleR)
- Переходим в настройки расписания
- И настраиваем расписание запуска скрипта:
- При запуске скрипта создается файл логов, где можно отслеживать успешные/неуспешные запуски.
- При создании второго расписание для скрипта с тем же названием, предыдущее расписание удаляется.
- Если компьютер выключен в момент, когда должен запуститься скрипт, то скрипт не будет запущен до следующего времени в расписании, либо до ручного запуска. Но при следующем запуске все данные (которые не были записаны в прошлом спарсятся при условии, если прошло не более 90 дней между запусками)
Более детально о том, как настроить расписание запуска R скрипта.
Выводы
- Использования данного скрипта помогает существенно облегчить задачу получение и сохранения данных из Search Console.
- Возможность автоматического обновления данных помогает ускорить процесс работы.
- На выходе получаем данные, структурированные как tidy data, что помогает создавать любые BI модели и отчеты. Например,
очень круто!!! спасибо огромное!!!
Отлично, но оно тянет все метрики. А как мне в таком случае вытащить только позиции?
В функции search_analytics() это нельзя отрегулировать, но при необходимости можно после получение окончательного data frame (после вызова цикла) удалить «ненужные» колонки методом присвоения колонкам data frame NULL . Например, data$clicks <- NULL. Так как позиции, клики и показы получаем в функции линейно, то на скорости парсинга данных это не скажется.
спасибо за статью,
taskscheduleR только под win ставится? под mac не получилось..
У mac другая программа для шедулинга задач. Сама не тестила, но вроде как тут есть готовое решение https://www.r-bloggers.com/how-to-source-an-r-script-automatically-on-a-mac-using-automator-and-ical/amp/
Спасибо, потестим
Скажите, пожалуйста, есть ли подобное решение для экспорта данных из Яндекс Вебмастер?
Насколько мне известно готового пакета для R, который бы смог это делать нет. Тут необходимо писать свой пакет для парсинга данных с ЯВ API
Нашла такой пакет для ЯВ, но насколько я поняла, там есть все, кроме истории запросов:) https://github.com/igor-alexandrov/yandex-webmaster
Пакет для API v3 есть https://github.com/kutasok/ryandexwebmasterv3
!!!
Спасибо за статью.
У меня при выгрузки проблемы с кодировкой криллицы. В чём может быть проблема? Пример на скрине http://take.ms/bzqDS
Спасибо.
Прошу прощения, ответ есть в статье 🙂
Возникла другая проблема. При запросе с walk_data=(«byDate»), возникает ошибка http://take.ms/Wgtz7, вчера всё работало. Сегодня вот такая беда.
Была похожая проблема, по-моему. Решила отключить byDate. Использую просто walk_data = ‘none’ и загоняю в цикл и вручную по одному дню собираю. В статье готовое решение с циклом: http://prntscr.com/es82ko
Благодарю. Сейчас испытаю.
Подскажите, пожалуйста, можно ли связать Search Console и Google Bigquery и на основе userId или id электронной коммерции связать данные о запросе и покупке?
Или упрощенно, можно ли разметить запросы на основе userId в Search Console?
Здравствуйте!
Связать данные таким образом не получится, так как в Search Console нет данных о юзерах (ни user id, ни id коммерции). Можно связать на уровне урла.
Здравствуйте, Анастасия. А этот метод применим для выгрузки бэклинков из той же серч консоли? Хочется получить список с группировкой:
ссылающаяся страница | анкор | страница моего сайта. Тут что-то можно придумать?
К сожалению, сам google search console api не позволяет выгружать бэклинки
Анастасия добрый день , не заходит # Авторизация в аккаунт Google
и при установке библиотеки :
> library(googleAuthR)
2017-11-13 10:30:53> No scopes have been set, set them via
options(googleAuthR.scopes.selected) —
no authentication attempted.
ошибка «Error in init_oauth_service_account(self$secrets, scope = self$params$scope, :
Bad Request (HTTP 400).»
подскажите , в чем может быть проблема?
options(«googleAuthR.scopes.selected» = c(«https://www.googleapis.com/auth/webmasters»,
«https://www.googleapis.com/auth/analytics»,
«https://www.googleapis.com/auth/tagmanager.readonly»))
gar_auth_service(«C:/Users/…/ваш-ключ.json», scope = getOption(«googleAuthR.scopes.selected»))
Обновите скоупы и авторизируйтесь ещё раз
Спасибо , токен пустило , но потом вывело ошибку
» Error: API returned: User does not have sufficient permission for site»
[хотя я добавил в серч консоле аккаунт с фул правами (в поле email
ввел идентификатор сервисного аккаунта)
~~~
#В настройках включаем полный доступ к аккаунту.
http://joxi.ru/KAgkl7Qi401GxA вот так должно быть?
спасибо , жду вашего ответа )
Имя можете выбрать любое. В доступах Search Console нужно указать id сервисного аккаунта отсюда http://prntscr.com/h9uqy4
Когда создаете аккаунт, скачиваете json файл и путь к нему прописываете в R скрипте
я заново попробовал создать сервисный аккаунт и связать его с серч консолью с новым json файлом , но ничего не изменилось ,мне в скрипте выводит ту же ошибку . Может ли быть проблема в неправильной установке install.packages(«googleAuthR») http://joxi.ru/vAW47Rgh1z7V3r ?
Насколько я вижу, то все пакеты норм установились. Вероятнее всего где-то что-то не так именно с доступами. Попробуйте пройти аутентификацию через gar_auth() без настройки сервисного аккаунта, просто через google почту.
Анастасия спасибо за ответ удалось авторизоваться через сервисный аккаунт , фаил с ключами скачивается при ручном запуске , единственное дублируется информация в разрезе dimensions = c(‘date’,’page’,’query’,’country’) , как этого избежать ? или так и должно быть ( строка полностью повторяеться через N строк (по убыванию количества кликов) ,
Еще вопрос по автоматизации скрипта , тестирую одноразовый запуск через addins => schedule R . В файле записи логов информация об ошибке :
_________
#Installing package into ‘C:/Users/den/Documents/R/win-library/3.3’
#(as ‘lib’ is unspecified)
#Error in contrib.url(repos, «source») :
# trying to use CRAN without setting a mirror
#Calls: install.packages -> contrib.url
#Execution halted
_________
Спасибо за статью! очень полезная
Добрый день, не получается пройти авторизацию, помогите решить проблему. Спасибо. Скрин — http://prntscr.com/hxxqm5
Вам также нужно обновить скоупы.
options(«googleAuthR.scopes.selected» = c(«https://www.googleapis.com/auth/webmasters»,
«https://www.googleapis.com/auth/analytics»,
«https://www.googleapis.com/auth/tagmanager.readonly»))
А затем снова вызвать функцию авторизации с указанными скоупами.
gar_auth_service(«C:/Users/…/ваш-ключ.json», scope = getOption(«googleAuthR.scopes.selected»))
Спасибо за ответ. На моем скриншоте видно, что я уже пыталсся сделать запрос options(«googleAuthR.scopes.selected» = c(«https://www.googleapis.com/auth/webmasters»,
«https://www.googleapis.com/auth/analytics»,
«https://www.googleapis.com/auth/tagmanager.readonly»)) но у меня ошибку выдает.
Также, я подозоеваю что не подключается бибилиотека — library(searchConsoleR) , т.к. после это команды нет никакого ответа от консоли — это тоже видно на скриншоте. Не знаете в чем проблема?
1) Скоупы не присваиваются у вас потому что сначала нужно заменить кавычки с таких « на такие » в функции options.
После этого вызвать функцию gar_auth_service(«C:/Users/…/ваш-ключ.json» , scope = getOption(«googleAuthR.scopes.selected»)) с параметром scope.
2) По поводу библиотеки все норм. Если не возникает сообщения с ошибкой, значит библиотека подключилась корректно.
Разобрался, что нужно заменить кавычки)
Теперь следующая проблема — не могу установить что-то из гитхаба — http://prntscr.com/hxypzg
Подскажите, фильтрую данные:
dimensionFilterExp = c(‘query!~Україна’,’query!~політика’)
Но фильтруются только запросы на английском языке, а русском и украинском — все равно пропускает. Такое чувство, что кодировку не понимает. Что может быть и как это исправить?