Анализ SEO может занять время, но автоматизация процесса помогает устранить повторяющиеся задачи и ускорить важные оптимизации веб -сайта.
Это руководство покажет вам, как создать персональный инструмент с использованием Google Sheets, Google Search Console (GSC) и API CHATGPT для рационализации аудитов SEO и получения информации, основанной на ИИ.
С помощью этого инструмента вы можете:
- Автоматизируйте восстановление данных GSC для более быстрого анализа.
- Используйте ИИ, чтобы генерировать полезные рекомендации по ссылке.
План? Вы выбираете URL -адрес в поле, подключенном к GSC, введет свой клавиш API CHATGPT, проверяет страницу и запустите анализ, возглавляемый AI — All in Google Sheets.
Содержание
- 1 Какой анализ SEO Automati?
- 1.1 Шаг 1: Создайте лист Google для вашего инструмента
- 1.2 Шаг 2: Заполните свой лист
- 1.3 Шаг 3: Создать облачный проект Google
- 1.4 Шаг 4: Создайте сценарий приложения
- 1.5 Шаг 5: Добавьте доступ к доступу
- 1.6 Шаг 6: Зайдите в облачный проект Google для данных GSC
- 1.7 Шаг 7: Назовите свой скрипт приложений Google
- 1.8 Шаг 8: Измените файл манифеста
- 2 Поместите наш лист простыней, GSC и CHATGPT
Какой анализ SEO Automati?
После настройки этот инструмент позволит вам быстро получить доступ к данным ключей GSC, включая рейтинг ключевых слов, эталонные URL -адреса, дату последнего сайта и индексацию состояния в robots.txt.
CHATGPT улучшает процесс, анализируя и предоставляя рекомендации для:
Хотя этот сценарий не охватывает все, он предоставляет подробную информацию на страницах за несколько секунд, что позволяет вам сохранять ручное рабочее время.
Затем вы можете проконсультироваться с рекомендациями и решить, какие оптимизации реализуют.

Конфигурация вашего сценария может изначально казаться ошеломляющей, но внимательно следуйте каждому шагу и скопируйте сценарий, чтобы убедиться, что все работает.
Вам понадобится несколько вещей, чтобы начать:
Затем я проведу вас через свой процесс в восьми шагах, чтобы поместить этот «инструмент».
Шаг 1: Создайте лист Google для вашего инструмента
Если у вас есть учетная запись Google, это так же просто, как следить за этими шагами:
- Откройте Google Drive.
- Получите доступ к папке, где вы хотите разместить свой инструмент.
- Справа -нажмите на на заднем плане.
- Выбирать Google Leaves> пустая таблицаПолем
Вы можете переименовать лист на все, что вам нравится, но я выбрал следующее: GSC Custom Tool.


Шаг 2: Заполните свой лист
Заполните лист, тщательно выполнив эти шаги:
- Добавьте слова «выберите свойство GSC» в
A1
Полем - Добавить слова «выберите URL», чтобы
A2
Полем
Идти в A15
И добавить «результаты проверки». Под этим, в порядке A15
имеет A25
Добавьте следующее:
- URL:
- Одеяло:
- Robots.txt:
- Состояние индексации:
- Последняя рампа:
- Google Canonical:
- Канонический пользователь:
- Мобильная радость:
- Богатые результаты приемлема:
- Ссылочный URL:
В D1
Вы будете наклеить свой API Chatgpt ключ. Если у вас нет этого ключа, обратитесь к ссылке выше и убедитесь, что вы получите один, чтобы заставить этот инструмент работать.
Добавить «результат анализа ИИ» в F1
И «Пригласить отправлено в Chatgpt» имеет G1
Полем
Теперь мы должны объединить несколько строк в этих двух столбцах. Вы будете объединяться F2
— F30
И G2
— G30
отдельно, следуя этим шагам:
- Выберите строки, чтобы слияние.
- Идти в Формат> Celes Fusion> слияние вертикальноПолем
Повторите этот шаг для строк F и G, которые вы должны слиться.


Шаг 3: Создать облачный проект Google
Создать Google Cloud Console Project для инструмента.
После настройки создайте новый проект под названием «GSC Custom Tool».


Вы можете сделать это, отправившись Выберите проект> Новый проект И заполните информацию, как на скриншоте выше.
Нажимать Создавать Когда вы закончили назначить проект.
Теперь подключите консоли Google Search API к вашему проекту.


Доступ к панели поиска и введите «Консоль поиска Google», выберите ее, затем нажмите Давать возможность На следующем экране.


У нас еще многое предстоит сделать и вскоре вернуться к этому проекту.
Шаг 4: Создайте сценарий приложения
Интегрируйте скрипт приложений в свой недавно созданный файл Google Sheets.


Для этого откройте свой файл, затем перейдите к Расширения> Сценарий приложений. Скопируйте и приклеите код, который я создал ниже.
(Вы можете сделать это, выбрав код внутри окна и нажав Ctrl + C. вернуться к сценарию вашего приложения и нажмите Ctrl + V, чтобы прикрепить код.)
Ударять ОК> Сохраните проект> Выполнить.
Google пригласит вас проконсультироваться со всеми разрешениями и выбрать соответствующую учетную запись со всеми вашими связанными данными консоли поиска Google.
Копайте глубже: 5 сценариев Python для автоматизации SEO -задач
Спросите специалистов по маркетингу в области рассылки.
Шаг 5: Добавьте доступ к доступу
Вернитесь в свою консоль Cloud Google, чтобы внести другие настройки.
Нажмите Идентификационная информация На левой стороне экрана:


Нажмите + Создать идентификационную информацию В верхней части экрана и выберите OAuth Customer IdПолем
Идти в Настройте экран согласия и выберите ВнешнийПолем Создайте экран, затем введите свой:
- Имя приложения.
- Управление электронной почтой (связано с учетной записью GSC).
- Разработчик координирует.
Сохраните и продолжайте на следующем экране, который говорит Добавить или удалить пособияПолем
Выбирать Google Search Console API Scopes и обновление. ТАК, Сохраните и продолжайтеПолем
Добавьте пользователей, к которым вы хотите предоставить доступ, затем нажмите Сохраните и продолжайтеПолем
Шаг 6: Зайдите в облачный проект Google для данных GSC
Нажмите на значок гамбургера и перейти к Облачная презентация> Панель панелиПолем
Вы хотите скопировать на свой Номер проектакоторый находится на странице.

Добавьте имя для вашего сценария, чтобы сохранить организованные вещи.
Чтобы сделать это, иди История проектаНажмите на Единица В верхней части экрана и введите «персонализированный инструмент GSC».


Шаг 8: Измените файл манифеста
Теперь вы вернетесь к своему Параметры проекта и нажмите Показать «Appsscript.json» в редакторе.
Внутри издателя перейдите на appsscript.json и замените все в файле на код ниже:
{
"timeZone": "America/New_York",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"
"
"
"
"
],
"runtimeVersion": "V8"
}
Как только вы все приклеиваете, вы перейдете в файл code.js и приклеить этот код:
// Store the OAuth token and logs in script properties
const scriptProperties = PropertiesService.getScriptProperties();
const OPENAI_URL = "
const SYSTEM_MESSAGE = { role: "system", content: "You are a helpful SEO expert." };
function log(message) {
Logger.log(message); // Regular Apps Script logging
const logs = scriptProperties.getProperty('customLogs') || '';
scriptProperties.setProperty('customLogs', logs + '\n' + message); // Append message to logs
}
function resetLogs() {
scriptProperties.deleteProperty('customLogs'); // Clear logs for a new execution
}
function getLogs() {
return scriptProperties.getProperty('customLogs') || 'No logs available.';
}
function fetchOAuthToken() {
let token = scriptProperties.getProperty('oauthToken');
if (!token) {
token = ScriptApp.getOAuthToken();
scriptProperties.setProperty('oauthToken', token);
log('OAuth token fetched and stored.');
}
return token;
}
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('Search Console')
.addItem('Authorize GSC', 'promptReauthorization')
.addItem('Fetch GSC Properties', 'fetchGSCProperties')
.addItem('Inspect URL', 'inspectUrl') // Add the Inspect URL button
.addItem('AI Analyze', 'aiAnalyze') // Add the AI Analyze button
.addToUi();
}
function promptReauthorization() {
const ui = SpreadsheetApp.getUi();
const response = ui.alert(
'Re-authorize Script',
'Re-authorizing will revoke current permissions and require you to authorize again. Do you want to continue?',
ui.ButtonSet.YES_NO
);
if (response === ui.Button.YES) {
try {
scriptProperties.deleteProperty('oauthToken'); // Clear old token
const token = fetchOAuthToken(); // Fetch and store new token
log("OAuth Token: " + token);
ui.alert('Authorization successful. No further action is required.');
} catch (e) {
ui.alert('Authorization failed: ' + e.toString());
}
} else {
ui.alert('Re-authorization canceled.');
}
}
function fetchGSCProperties() {
resetLogs();
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const oauthToken = fetchOAuthToken();
const sites = getSitesListFromGSC(oauthToken);
if (!sites || sites.length === 0) {
SpreadsheetApp.getUi().alert('No GSC properties found. Please ensure you have access to GSC properties.');
return;
}
const siteUrls = ['Select a property'].concat(
sites.map(site => site.siteUrl).sort()
);
sheet.getRange('A1').setValue('Select GSC property').setFontWeight('bold');
sheet.getRange('B1').setDataValidation(
SpreadsheetApp.newDataValidation()
.requireValueInList(siteUrls, true)
.build()
);
sheet.getRange('B1').setValue('Select a property').setFontWeight('bold');
sheet.setColumnWidth(1, 150);
sheet.setColumnWidth(2, 350);
}
let isProcessing = false; // Global flag to prevent recursive triggering
function onEdit(e) {
if (isProcessing) return; // Prevent re-entry during execution
isProcessing = true; // Set flag to true
try {
resetLogs();
const sheet = e.source.getActiveSheet();
const range = e.range;
// Always clear A3:D30 on edits to B1 or B2
if (range.getA1Notation() === 'B1' || range.getA1Notation() === 'B2') {
sheet.getRange('A3:D30').clearContent();
sheet.getRange('F1:G30').clearContent();
if (range.getA1Notation() === 'B1') {
const selectedProperty = range.getValue();
// Clear A2 and set loading state
sheet.getRange('A2').setValue('Loading results...').setFontWeight('bold');
sheet.getRange('B2').clearContent();
if (selectedProperty === 'Select a property') {
sheet.getRange('A2').clearContent();
sheet.getRange('B2').clearContent();
return;
}
const oauthToken = fetchOAuthToken();
const urls = getUrlsForProperty(selectedProperty, oauthToken);
if (!urls || urls.length === 0) {
sheet.getRange('A2').setValue('No URLs found').setFontWeight('bold');
sheet.getRange('B2').clearContent();
log(`No URLs found for property ${selectedProperty}`);
return;
}
sheet.getRange('A2').setValue('Select a URL').setFontWeight('bold');
sheet.getRange('B2').setDataValidation(
SpreadsheetApp.newDataValidation()
.requireValueInList(['Select a URL'].concat(urls), true)
.build()
);
sheet.getRange('B2').setValue('Select a URL').setFontWeight('bold');
}
if (range.getA1Notation() === 'B2') {
const selectedProperty = sheet.getRange('B1').getValue();
const selectedUrl = range.getValue();
if (selectedUrl === 'Select a URL') {
return;
}
sheet.getRange('A3').setValue('Loading keywords...').setFontWeight('bold');
const oauthToken = fetchOAuthToken();
const keywords = getTopKeywordsForUrl(selectedProperty, selectedUrl, oauthToken);
if (!keywords || keywords.length === 0) {
sheet.getRange('A3').setValue('No keywords found').setFontWeight('bold');
log(`No keywords found for URL ${selectedUrl}`);
return;
}
// Populate keywords and metrics
sheet.getRange('A3:D12').clearContent(); // Clear any loading message
keywords.forEach((keyword, index) => {
if (index row.keys[0]) : [];
} else {
throw new Error(`Failed to fetch data: ${response.getResponseCode()} - ${response.getContentText()}`);
}
} catch (e) {
log(`Error: ${e.toString()}`);
return [];
}
}
function getTopKeywordsForUrl(property, url, oauthToken) {
try {
const apiUrl = `
log(`API URL: ${apiUrl}`);
log(`OAuth Token: ${oauthToken}`);
const payload = {
startDate: getThreeMonthsAgo(),
endDate: getToday(),
dimensions: ["query"],
dimensionFilterGroups: [
{
filters: [
{
dimension: "page",
operator: "equals",
expression: url
}
]
}
],
rowLimit: 10,
orderBy: [{ fieldName: "clicks", sortOrder: "DESCENDING" }]
};
log(`Payload: ${JSON.stringify(payload)}`);
const headers = {
Authorization: `Bearer ${oauthToken}`,
"Content-Type": "application/json"
};
const options = {
method: "post",
contentType: "application/json",
headers: headers,
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(apiUrl, options);
log(`Response Code: ${response.getResponseCode()}`);
log(`Response: ${response.getContentText()}`);
if (response.getResponseCode() === 200) {
const json = JSON.parse(response.getContentText());
return json.rows ? json.rows.map(row => ({
query: row.keys[0],
clicks: row.clicks,
impressions: row.impressions,
ctr: row.ctr
})) : [];
} else {
throw new Error(`Failed to fetch data: ${response.getResponseCode()} - ${response.getContentText()}`);
}
} catch (e) {
log(`Error: ${e.toString()}`);
return [];
}
}
function getToday() {
const today = new Date();
return today.toISOString().split("T")[0];
}
function getThreeMonthsAgo() {
const date = new Date();
date.setMonth(date.getMonth() - 3);
return date.toISOString().split("T")[0];
}
function inspectUrl() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const url = sheet.getRange('B2').getValue();
const property = sheet.getRange('B1').getValue();
// Clear previous inspection results in A15:D30
sheet.getRange('A15:D30').clearContent();
sheet.getRange('A15').setValue('Inspecting...').setFontWeight('bold');
if (!url || url === 'Select a URL') {
SpreadsheetApp.getUi().alert('Please select a valid URL in cell B2 before inspecting.');
sheet.getRange('A15').setValue('No URL selected').setFontWeight('bold');
return;
}
const oauthToken = fetchOAuthToken();
try {
const result = callUrlInspectionApi(property, url, oauthToken);
// Extract fields from the response
const indexStatus = result.indexStatusResult || {};
const mobileUsability = result.mobileUsabilityResult || {};
const richResults = result.richResultsInfo || {};
const referringUrls = indexStatus.referringUrls?.join(', ') || 'None';
// Populate inspection results in the sheet
sheet.getRange('A15').setValue(`Inspection Results`).setFontWeight('bold');
sheet.getRange('A16').setValue(`URL:`).setFontWeight('bold');
sheet.getRange('B16').setValue(url);
sheet.getRange('A17').setValue(`Coverage:`).setFontWeight('bold');
sheet.getRange('B17').setValue(indexStatus.coverageState || 'Unknown');
sheet.getRange('A18').setValue(`Robots.txt:`).setFontWeight('bold');
sheet.getRange('B18').setValue(indexStatus.robotsTxtState || 'Unknown');
sheet.getRange('A19').setValue(`Indexing State:`).setFontWeight('bold');
sheet.getRange('B19').setValue(indexStatus.indexingState || 'Unknown');
sheet.getRange('A20').setValue(`Last Crawled:`).setFontWeight('bold');
sheet.getRange('B20').setValue(indexStatus.lastCrawlTime || 'Not Available');
sheet.getRange('A21').setValue(`Google Canonical:`).setFontWeight('bold');
sheet.getRange('B21').setValue(indexStatus.googleCanonical || 'Unknown');
sheet.getRange('A22').setValue(`User Canonical:`).setFontWeight('bold');
sheet.getRange('B22').setValue(indexStatus.userCanonical || 'Unknown');
sheet.getRange('A23').setValue(`Mobile Usability:`).setFontWeight('bold');
sheet.getRange('B23').setValue(mobileUsability.verdict || 'Unknown');
sheet.getRange('A24').setValue(`Rich Results Eligibility:`).setFontWeight('bold');
sheet.getRange('B24').setValue(richResults.verdict || 'Unknown');
sheet.getRange('A25').setValue(`Referring URLs:`).setFontWeight('bold');
sheet.getRange('B25').setValue(referringUrls);
// Log and alert full response for debugging
const fullResponse = JSON.stringify(result, null, 2);
log(`Full Inspection Result: ${fullResponse}`);
//SpreadsheetApp.getUi().alert(`Inspection Completed. Full Response:\n\n${fullResponse}`);
} catch (error) {
sheet.getRange('A15').setValue('Inspection Failed').setFontWeight('bold');
log(`Error inspecting URL: ${error.message}`);
SpreadsheetApp.getUi().alert(`Error inspecting URL: ${error.message}\n\nLogs:\n${getLogs()}`);
}
}
function callUrlInspectionApi(property, url, oauthToken) {
const apiUrl="
const payload = {
siteUrl: property,
inspectionUrl: url,
languageCode: 'en-US'
};
const headers = {
Authorization: `Bearer ${oauthToken}`,
'Content-Type': 'application/json'
};
const options = {
method: 'post',
contentType: 'application/json',
headers: headers,
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
log(`API URL: ${apiUrl}`);
log(`Payload: ${JSON.stringify(payload)}`);
try {
const response = UrlFetchApp.fetch(apiUrl, options);
const responseCode = response.getResponseCode();
const responseText = response.getContentText();
log(`Response Code: ${responseCode}`);
log(`Response Content: ${responseText}`);
if (responseCode === 200) {
const jsonResponse = JSON.parse(responseText);
if (jsonResponse && jsonResponse.inspectionResult) {
return jsonResponse.inspectionResult;
} else {
log(`Unexpected API Response Structure: ${responseText}`);
throw new Error('Unexpected API response format. "inspectionResult" field is missing.');
}
} else {
log(`Failed API Call: ${responseText}`);
throw new Error(`Failed to inspect URL. Response Code: ${responseCode}. Response: ${responseText}`);
}
} catch (error) {
log(`Error during API call: ${error}`);
throw new Error(`Error inspecting URL: ${error.message}`);
}
}
function callChatGPT(prompt, temperature = 0.9, maxTokens = 800, model = "gpt-3.5-turbo") {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const secretKey = sheet.getRange('D1').getValue().trim(); // Retrieve the OpenAI API key from D1
if (!secretKey) {
throw new Error("API Key is missing in cell D1. Please provide a valid OpenAI API key.");
}
const payload = {
model: model,
messages: [
SYSTEM_MESSAGE,
{ role: "user", content: prompt }
],
temperature: temperature,
max_tokens: maxTokens
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + secretKey
},
payload: JSON.stringify(payload)
};
try {
const response = UrlFetchApp.fetch(OPENAI_URL, options);
const responseData = JSON.parse(response.getContentText());
if (responseData.choices && responseData.choices[0] && responseData.choices[0].message) {
return responseData.choices[0].message.content.trim();
} else {
log("Unexpected response format from OpenAI: " + JSON.stringify(responseData));
return "Sorry, I couldn't process the request.";
}
} catch (error) {
log("Error calling OpenAI API: " + error);
return "Sorry, there was an error processing your request.";
}
}
function aiAnalyze() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const url = sheet.getRange('B2').getValue();
const keywords = sheet.getRange('A3:A12').getValues().flat().filter(Boolean); // Get non-empty keywords
const inspectionData = sheet.getRange('A16:B20').getValues();
// Validate input fields
if (!url || keywords.length === 0 || inspectionData.some(row => row.length `${row[0]}: ${row[1]}`).join("\n")}
Suggest a short list of specific recommendations on how I can improve the page's SEO. Make sure the recommendations include details such as change this to that, or add something, etc... Be concrete with SEO recommendations.
`;
// Display the prompt in G1
sheet.getRange('G1').setValue("Prompt Sent to ChatGPT").setFontWeight("bold");
sheet.getRange('G2:G30').clearContent(); // Clear previous content in column G
sheet.getRange('G2:G30').merge(); // Merge cells G2:G30
sheet.getRange('G2').setValue(prompt).setVerticalAlignment("top"); // Add the prompt and align to top
sheet.setColumnWidth(7, 400); // Set column G width to 400px
// Call ChatGPT API
const analysisResult = callChatGPT(prompt);
// Display the result in the spreadsheet (Column F)
sheet.getRange('F1').setValue("AI Analysis Result").setFontWeight("bold");
sheet.getRange('F2:F30').clearContent(); // Clear previous content
sheet.getRange('F2:F30').merge(); // Merge the cells
sheet.getRange('F2').setValue(analysisResult).setVerticalAlignment("top"); // Add the AI result and align to top
sheet.setColumnWidth(6, 400); // Set column F width to 400px
// Log the response
log("AI Analysis Completed: " + analysisResult);
}
После завершения вернитесь к своим простыням, обновите и используйте новый Консоль исследования> Свойства восстановления GSCПолем
Следуйте подсказкам, пока вы не попросите вас выбрать используемую учетную запись, и, наконец, выберите приложение, которое вы планируете использовать.
Если все идет хорошо, вы можете перейти к захватывающей части, чтобы собрать ее вместе и запустить свой первый анализ SEO, используя ваш новый сценарий.
Поместите наш лист простыней, GSC и CHATGPT
Вы сделали многое многое, но пришло время увидеть инструмент в действии. Вот как это работает:


- Идти в Исследовательская консоль> Авторизировать GSC.
Убедитесь, что вы используете учетную запись, на которой подключен домен GSC; В противном случае это не сработает.
- Идти в Исследовательская консоль> Резюме GSC Properties.
Теперь вы заметите, что Выберите свойство GSC имеет B1
На листе заполнен. Выберите домен, который вы хотите проанализировать, затем выберите URL B1
На листе.
- Идти в Исследовательская консоль> Проверьте URL.
А Результаты проверки на листе заполнят и предложат вам множество информации на странице, такую как покрытие, последняя дата разведки и т. Д.
Наконец, мы вернемся в последний раз и сделаем следующее:
- Идти в Исследовательская консоль> Анализ.
Вся информация о «результате анализа ИИ» теперь будет выполнена, предлагая вам информацию о ключевых элементах страницы и указав точные шаги, которые вы можете предпринять для улучшения страницы.
Я не рекомендую слепо следовать инструкциям, но они предлагают полезные шаги, которые вы можете выполнить, чтобы укрепить страницу.
Если вы хотите изменить подсказку CHATGPT, чтобы добавить свои индивидуальные данные, получите доступ к ячейке G2
,, Прямо под разделом, который указывает «Приглашение, отправленное в Чэтгпт».
Отличная работа! У вас есть рабочий сценарий, который может ускорить ваш анализ SEO и сделать ваш день более полезным.
Комбинация листьев, GSC и CHATGPT помогли мне стать более эффективным и позволить мне тратить больше времени на оптимизацию и анализировать менее тысячи страниц.
Опыт со сценарием и найдите новые способы сделать себя.
Вы глубже: 15 инструментов ИИ, которые вы должны использовать для SEO
Авторам взносов предлагается создать контент для поисковых земель и выбираются для их опыта и их вклада в исследовательское сообщество. Наши участники работают под надзором редакционных сотрудников, и взносы подтверждаются на качество и актуальность для наших читателей. Мнения, которые они выражают, являются их.