Автоматизация - Индексирование сайтов с помощью Google Indexing API на Python

Содержание:

Как использовать код из статьи

Я размещу код на Гитхабе в формате Jupyter Notebook – думаю, что так нагляднее.

Установите питон и сборку библиотек Anaconda.

Скачайте папку с Гитхаба. В ней будет:

  • файл google_indexing_api.ipynb с кодом и комментариями,
  • таблица davita.xlsx, которая используется в качестве примера в первом скрипте,
  • специальный json-ключ, который используется для API.

Подготовка

Регистрация приложения

1. Перейти https://console.cloud.google.com/

2. Выбрать Select Project:

3. Нажать New Project:

4. Написать название проекта и нажать Create:

5. Когда проект создастся, нажать на колокольчик и выбрать по названию (на этом скрине у меня проект называется «Project Name»):

6. Навести курсор на APIs & Services, выбрать Credentials (на этом скрине у меня проект называется «Project Name 2»):

7. В разделе Service Accounts нажать Manage service accounts:

8. Нажать Create service account:

9. Написать название, нажать Done:

10. Затем нажать на три точки и выбрать Manage keys:

11. Нажать на Add Key, затем выбрать Create new key:

12. Выбрать JSON и нажать Create:

13. Скачанный файл разместить в папке с кодом.

14. Набрать в поиске Indexing Api:

15. Нажать Enable:

Настройка Google Search Console

1. Перейти в настройки проекта:

2. Выбрать Пользователи и разрешения:

3. Нажать Добавить пользователя, появится форма, где нудно указать Service account, который был создан ранее:

4. Скопировать Service Account из Google Cloud:

5. Вставить в форму в Google Search Console, в разрешениях поставить статус Владелец:

Установка специальных библиотек

Для отправки страниц на индексирование понадобятся:

  • httplib2
  • oauth2client.service_account

Доки:

1. В терминале или командной строке напишите pip install google-api-python-client.

2. Если вы используете Anaconda, перейдите в Navigator, выберете вкладку Environment, через поиск найдите:

httplib2, поставьте галочки:

oauth2client, поставьте галочку:

Или напишите pip install google-api-python-client в Jupyter:

Отправка URL на индексирование

Разместите json-ключ в папке с кодом:

Импорт библиотек

import json
import time
import requests
 
import httplib2
from oauth2client.service_account import ServiceAccountCredentials
 
import pandas as pd

Настройки

Ресурсы для отправки:

SCOPES = ["https://www.googleapis.com/auth/indexing"]
ENDPOINT = "https://indexing.googleapis.com/v3/urlNotifications:publish"

Параметры проекта:

key = 'davita-301710-699786f70a1b'
project_name = 'davita'

Загрузка URL для индексирования

Файл в формате xlsx с названием поля "urls":

table_with_urls_for_recrawl = pd.read_excel(f'{project_name}.xlsx')

Отправка на индексирование

Функция принимает множество (set) url и ключ,
отправленные адреса добавляет в отдельный set,
пишет ответ и количество отправленных страниц,
возвращает set отправленных страниц.

def send_pages_to_google_for_recrawl(data, key):
 
    json_key_file = f"{key}.json"
    credentials = ServiceAccountCredentials.from_json_keyfile_name(json_key_file, 
                                                                   scopes=SCOPES)
    http = credentials.authorize(httplib2.Http())
 
    sent_urls_for_recrawl_set = set()
    for url in data:
 
        urls = {'url''{}'.format(url),
                'type''URL_UPDATED'}
 
        response, content = http.request(ENDPOINT, method="POST", 
                                        body=json.dumps(urls))
 
        time.sleep(1)
 
        if response['status'] != '200':
            break
 
        sent_urls_for_recrawl_set.add(url)
 
    sent_urls_set_len = len(sent_urls_for_recrawl_set)
 
    print(response['status'])
    print(content.decode())
 
    print('На переобход отправлено:', sent_urls_set_len)
 
    return sent_urls_for_recrawl_set

Удаление из списка и экспорт

Функция принимает set с со всеми адресами из загруженной таблицы и set отправленных url,
Из загруженной таблицы удаляются url, которые были отправлены. Это нужно для того, чтобы в следующий раз, когда обновится квота, эти же страницы не оправлялись на переобход.

Экспорт

def export_data_to_excel(data):
    project_report = pd.ExcelWriter(f'{project_name}.xlsx', engine='xlsxwriter')
    data.to_excel(project_report, index=False)
    project_report.save()

Удаление и экспорт

def delete_sent_urls_and_export_new_table(main_urls_set, sent_urls_for_recrawl_set):
 
    main_urls_set_without_sent_urls = main_urls_set - sent_urls_for_recrawl_set
 
    rest_urls_list = list(main_urls_set_without_sent_urls)
 
    data = pd.DataFrame({'urls': rest_urls_list})
 
    export_data_to_excel(data)

Главная функция

Принимает датафрейм, который был загружен в начале,
преобразует датафрейм в set,
отправляет на переобход,
удаляет из общего списка отправленные url и экспортирует датафрейм.

def main_send_pages_to_google_for_recrawl(data):
 
    main_urls_set = set(data['urls'].to_list())
 
    sent_urls_for_recrawl_set = send_urls_to_yandex_for_recrawl(main_urls_set, user_id, host)
 
    delete_sent_urls_and_export_new_table(main_urls_set, sent_urls_for_recrawl_set)

Запуск

main_send_pages_to_google_for_recrawl(table_with_urls_for_recrawl)

Ответ 429 со статусом «Quota exceeded». Стандартная квота на проект – 200 URL.

Подробнее про квоты.

Другие ответы и статусы.

Увеличение квоты Indexing API

Аккаунт gmail используется для авторизации Google Cloud Console, в котором создаются проекты (шаг 3 из раздела Регистрация приложения), на каждый проект выдается суточная квота в 200 адресов. На один gmail вы можете создать 12 проектов, каждый из которых можете использовать для отправки страниц разных проектов, а можете для одного сайта, тем самым увеличив квоту примерно до 2400 страниц (не всегда ровно 200 отправляется) в сутки.

На сколько я понял, есть два способа увеличить квоту на количество проектов и соответственно на количество отправляемых страниц:

  • Официальный через специальную форму для увеличения количества проектов в Google Cloud Console. Может вам ответят, а может и нет. Мне не ответили.
  • Использовать разные аккаунты gmail. Эту замечательную идею я взял из этой прекрасной статьи. Таким образом вы увеличиваете суточную квоту 2400 страниц во столько раз, сколько у вас gmail. Я пока не столкнулся с какими либо санкциями за такой абьюз системы Google, но на всякий случай не используйте аккаунты gmail, на которых сильно завязана ваша жизнь, работа, чтобы избежать блокировки важного аккаунта.

Создание таблицы с настройками

Вам нужно пройти путь создания для каждого gmail, для всех проектов, который описан в разделе Регистрация приложения – создание проекта, создание сервисного аккаунта, создание json-ключа, добавление сервисного аккаунта в настройки Google Search Console.

Заносите параметры каждого проекта в таблицу, для работы скрипта нужен будет только gmail (поле email) и имя json-ключа (поле key) без расширения. Дополнительно я заношу в таблицу название проекта и адрес сервисного аккаунта, который используется в Google Search Console:

Создаю папку с названием адреса gmail и кладу туда все соответствующие json-ключи:

Импорт библиотек

import json
import time
import requests
import traceback
 
import httplib2
from oauth2client.service_account import ServiceAccountCredentials
 
import pandas as pd

Настройки

Ресурсы для отправки:

SCOPES = ["https://www.googleapis.com/auth/indexing"]
ENDPOINT = "https://indexing.googleapis.com/v3/urlNotifications:publish"

Параметры проекта:

key_path = '{}/{}.json'
project_name = 'koleso'

Загрузка URL для индексирования

Файл в формате csv с названием поля "urls":

table_with_urls_for_recrawl = pd.read_csv(f'{project_name}.csv')

Обработка ошибок

def error_report():
    print('Ошибка')
    traceback.print_exc()

Отправка на индексирование

Функция принимает множество (set) url, ключ и email,
отправленные адреса добавляет в отдельный set,
пишет ответ и количество отправленных страниц,
возвращает set отправленных страниц.

def send_pages_to_google_for_recrawl(data, email, key):
 
    json_key_file = key_path.format(email, key)
 
    credentials = ServiceAccountCredentials.from_json_keyfile_name(json_key_file, 
                                                                   scopes=SCOPES)
    http = credentials.authorize(httplib2.Http())
 
    sent_urls_for_recrawl_set = set()
    for url in data:
 
        urls = {'url''{}'.format(url),
                'type''URL_UPDATED'}
 
        response, content = http.request(ENDPOINT, method="POST", 
                                        body=json.dumps(urls))
 
        time.sleep(0.5)
 
        if response['status'] != '200':
            break
 
 
        sent_urls_for_recrawl_set.add(url)
 
    #print(response['status'])
    for keys,values in json.loads(content.decode())['error'].items():
        print(values,'\n')
 
    sent_urls_set_len = len(sent_urls_for_recrawl_set)
 
 
    print('На переобход отправлено:', sent_urls_set_len,'\n')
 
    return sent_urls_for_recrawl_set

Удаление из списка и экспорт

Функция принимает set с со всеми адресами из загруженной таблицы и set отправленных url,
Из загруженной таблицы удаляются url, которые были отправлены. Это нужно для того, чтобы в следующий раз, когда обновится квота, эти же страницы не оправлялись на переобход.

def delete_sent_urls_and_export_new_csv_table(main_urls_set, sent_urls_for_recrawl_set):
 
    print('Удаление отправленных URL','\n')
 
    main_urls_set_without_sent_urls = main_urls_set - sent_urls_for_recrawl_set
 
    print('Длина общего списка после удаления отправленных URL:', len(main_urls_set_without_sent_urls),'\n')
 
    rest_urls_list = list(main_urls_set_without_sent_urls)
 
    data = pd.DataFrame({'urls': rest_urls_list})
 
    print('Экспорт CSV','\n','\n')
 
    data.to_csv(f'{project_name}.csv', index=False)

Главная функция

Открывает таблицу «settings_indexing_api», из которой берется email и название ключа,
открывается csv-файл с адресами на отправку, конвертируется в set,
затем отправляется по доступной квоте,
отправленные адреса удаляются из общего списка, экспортируется csv-файл.

def main_send_pages_to_google_for_recrawl():
 
    settings = pd.read_excel('google_indexing_settings.xlsx').to_dict('records')
 
    total_sent_urls_counter = 0
 
    for row in settings:
        try:
            email, service_email, key = row['email'], row['service_account_email'], row['key']
 
            print(email)
            print(service_email,'\n')
 
            data = pd.read_csv(f'{project_name}.csv')
 
            print('Длина общего списка URL:', len(data))
            print('Конвертация в set')
 
            main_urls_set = set(data['urls'].to_list())
 
            print('Длина списка URL после конвертации в set:', len(main_urls_set),'\n')
 
            sent_urls_for_recrawl_set = send_pages_to_google_for_recrawl(main_urls_set, email, key)
 
            delete_sent_urls_and_export_new_csv_table(main_urls_set, sent_urls_for_recrawl_set)
 
            total_sent_urls_counter += len(sent_urls_for_recrawl_set)
 
            print('Ожидание 20 сек.','\n','\n')
            time.sleep(20)
 
        except:
            error_report()
 
    print('На переобход отправлено:', total_sent_urls_counter) 

Запуск

main_send_pages_to_google_for_recrawl()
# Теги

Работаю в агенстве Marronnier с 2015 года, занимаюсь продвижением сайтов в посковых системах.
© 2011- Интернет-агентство «Marronnier»     Рекомендуем хостинг сайтов BeGet     Автоматизация шинного бизнеса SelecTyre