Top 50 Custom Workflow and CRM Business Ideas for E-commerce Retailers to Boost Organic Search Growth by 200%
Automating Product Data Enrichment for SEO
A significant bottleneck for e-commerce SEO is the manual effort required to enrich product data with relevant keywords, long-tail variations, and schema markup. Automating this process can dramatically accelerate content creation and improve search visibility. We can leverage a combination of internal data analysis and external APIs to achieve this.
Consider a Python script that analyzes customer search queries (from your site’s search logs or Google Search Console data) and product descriptions to identify keyword gaps and opportunities. This script can then interface with a PIM (Product Information Management) system or directly update your e-commerce platform’s database.
1. Keyword-Driven Product Description Generation
This workflow focuses on programmatically generating unique, keyword-rich product descriptions. We’ll use a Python script that pulls data from your product catalog, analyzes top-performing keywords, and then uses a templating engine to construct new descriptions.
Prerequisites:
- Access to product catalog data (CSV, database, or API).
- A list of target keywords, ideally segmented by product category.
- Python 3.x installed.
- Libraries:
pandasfor data manipulation,jinja2for templating.
Workflow Steps:
- Data Ingestion: Load product data and keyword lists into pandas DataFrames.
- Keyword Mapping: Associate keywords with specific products or categories.
- Template Creation: Define Jinja2 templates for product descriptions, incorporating placeholders for product attributes and keywords.
- Description Generation: Iterate through products, select relevant keywords, and render descriptions using the templates.
- Output: Save generated descriptions to a CSV file or directly update your e-commerce platform via API.
Example Python Script Snippet:
import pandas as pd
from jinja2 import Environment, FileSystemLoader
# Load product data and keywords
products_df = pd.read_csv('products.csv')
keywords_df = pd.read_csv('keywords.csv')
# Merge keywords with products (assuming a 'category' column exists)
# This is a simplified merge; a more robust solution would involve fuzzy matching or NLP
merged_df = pd.merge(products_df, keywords_df, on='category', how='left')
# Set up Jinja2 environment
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('description_template.html')
# Generate descriptions
generated_descriptions = []
for index, row in merged_df.iterrows():
# Basic keyword selection (e.g., first 3 keywords for the category)
keywords = row['keywords'].split(',')[:3] if pd.notna(row['keywords']) else []
description = template.render(
product_name=row['product_name'],
features=row['features'].split('|') if pd.notna(row['features']) else [],
keywords=', '.join(keywords),
brand=row['brand']
)
generated_descriptions.append({'product_id': row['product_id'], 'generated_description': description})
descriptions_df = pd.DataFrame(generated_descriptions)
descriptions_df.to_csv('generated_descriptions.csv', index=False)
print("Generated descriptions saved to generated_descriptions.csv")
Example Jinja2 Template (description_template.html):
<h2>{{ product_name }} - {{ brand }}</h2>
<p>Discover the exceptional {{ product_name }} by {{ brand }}. This product is designed to enhance your experience with its top-tier features.</p>
<h3>Key Features:</h3>
<ul>
{% for feature in features %}
<li>{{ feature }}</li>
{% endfor %}
</ul>
<p>When searching for {{ keywords }}, look no further than the {{ product_name }}. It's the perfect choice for those seeking quality and performance.</p>
2. Automated Schema Markup Generation for Products
Implementing rich snippets via Schema.org markup is crucial for SEO. Manually adding this to thousands of products is impractical. We can automate this by generating JSON-LD snippets based on product data.
This workflow involves a script that reads product details (name, price, availability, image URL, reviews) and outputs structured JSON-LD data. This JSON can then be injected into your product pages’ `
` section or served via a sitemap.Workflow Steps:
- Data Extraction: Fetch product data including name, SKU, price, currency, availability, image URL, brand, and aggregate rating.
- Schema Mapping: Map product attributes to the appropriate Schema.org properties (e.g., `name` to `name`, `price` to `offers.price`, `availability` to `offers.availability`).
- JSON-LD Generation: Construct a JSON-LD object for each product.
- Integration: Embed the generated JSON-LD within the product page’s HTML or include it in a dedicated JSON-LD sitemap.
Example PHP Snippet for JSON-LD Generation:
<?php
function generateProductSchema($productData) {
// Basic validation and data preparation
$name = htmlspecialchars($productData['name']);
$sku = htmlspecialchars($productData['sku']);
$price = number_format($productData['price'], 2, '.', '');
$currency = htmlspecialchars($productData['currency']);
$availability = $productData['in_stock'] ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock';
$imageUrl = htmlspecialchars($productData['image_url']);
$brand = htmlspecialchars($productData['brand']);
$ratingValue = isset($productData['average_rating']) ? number_format($productData['average_rating'], 1) : null;
$reviewCount = isset($productData['review_count']) ? (int)$productData['review_count'] : null;
$schema = [
'@context' => 'https://schema.org/',
'@type' => 'Product',
'name' => $name,
'image' => [$imageUrl],
'description' => htmlspecialchars($productData['description']), // Assuming description is available
'sku' => $sku,
'mpn' => $sku, // Often MPN is the same as SKU
'brand' => [
'@type' => 'Brand',
'name' => $brand
],
'offers' => [
'@type' => 'Offer',
'url' => htmlspecialchars($productData['product_url']), // Assuming product URL is available
'priceCurrency' => $currency,
'price' => $price,
'availability' => $availability,
'seller' => [
'@type' => 'Organization',
'name' => 'YourCompanyName' // Replace with your company name
]
]
];
if ($ratingValue !== null && $reviewCount !== null) {
$schema['aggregateRating'] = [
'@type' => 'AggregateRating',
'ratingValue' => $ratingValue,
'reviewCount' => $reviewCount
];
}
// Encode as JSON-LD
return json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
// Example Usage:
$productData = [
'name' => 'Super Widget Pro',
'sku' => 'SWP-12345',
'price' => 99.99,
'currency' => 'USD',
'in_stock' => true,
'image_url' => 'https://example.com/images/swp-12345.jpg',
'description' => 'The ultimate widget for professionals.',
'brand' => 'Acme Corp',
'product_url' => 'https://example.com/products/super-widget-pro',
'average_rating' => 4.8,
'review_count' => 150
];
$jsonLd = generateProductSchema($productData);
// In a real application, you would echo this within a <script type="application/ld+json"> tag
// echo '<script type="application/ld+json">' . $jsonLd . '</script>';
// For demonstration, we'll just print it
echo $jsonLd;
?>
3. Dynamic Internal Linking Based on Content Similarity
Effective internal linking is a cornerstone of SEO, distributing link equity and improving crawlability. Manually linking every relevant product or category is time-consuming. A system that automatically suggests or implements internal links based on content similarity can be highly beneficial.
This workflow could involve using NLP techniques (like TF-IDF or word embeddings) to compare product descriptions, category pages, and blog posts. When a high similarity score is detected between two pieces of content, an internal link is suggested or automatically created.
Workflow Steps:
- Content Indexing: Extract text content from all relevant pages (products, categories, blog posts).
- Text Vectorization: Convert text into numerical vectors using methods like TF-IDF or sentence embeddings (e.g., using libraries like
scikit-learnorsentence-transformers). - Similarity Calculation: Compute cosine similarity between content vectors.
- Link Suggestion/Creation: Identify pairs of content with similarity above a defined threshold. Suggest links to a human editor or automatically insert links in a controlled manner.
Example Python Snippet (Conceptual using TF-IDF):
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
# Assume you have a DataFrame 'content_df' with columns 'url' and 'text'
# Example:
# content_df = pd.DataFrame({
# 'url': ['/products/widget-a', '/products/widget-b', '/blog/widget-guide'],
# 'text': ['Detailed description of widget A...', 'Widget B is similar to A...', 'A comprehensive guide to widgets...']
# })
# Placeholder for actual data loading
content_df = pd.DataFrame({
'url': ['/products/widget-a', '/products/widget-b', '/blog/widget-guide', '/category/widgets'],
'text': [
'The Super Widget A is a revolutionary device for home automation. It offers advanced features and seamless integration.',
'Widget B is an enhanced version of Widget A, providing more power and a sleeker design. Ideal for professional use.',
'A comprehensive guide to understanding and using widgets in your daily life. Learn about different types and their benefits.',
'Our widgets category features a wide range of products, including the popular Widget A and Widget B.'
]
})
vectorizer = TfidfVectorizer(stop_words='english')
tfidf_matrix = vectorizer.fit_transform(content_df['text'])
# Calculate cosine similarity
cosine_sim_matrix = cosine_similarity(tfidf_matrix, tfidf_matrix)
# Identify potential internal links
internal_links = []
threshold = 0.3 # Similarity threshold
for i, url1 in enumerate(content_df['url']):
for j, url2 in enumerate(content_df['url']):
if i != j and cosine_sim_matrix[i, j] >= threshold:
# Avoid duplicate links (e.g., A->B and B->A)
if (url2, url1) not in internal_links:
internal_links.append((url1, url2, cosine_sim_matrix[i, j]))
# Sort by similarity score (descending)
internal_links.sort(key=lambda x: x[2], reverse=True)
print("Potential Internal Links:")
for link1, link2, score in internal_links:
print(f"- Link from {link1} to {link2} (Score: {score:.4f})")
# In a real CRM/CMS, you would use this data to:
# 1. Present suggestions to an editor.
# 2. Automatically insert links within content (e.g., using regex or DOM manipulation).
# Be cautious with automatic insertion to avoid over-optimization or broken links.
4. Automated Content Refresh and Republishing Workflow
Stale content can negatively impact SEO. A workflow to periodically review and refresh existing content (blog posts, category pages) can boost rankings. This involves identifying underperforming or outdated content and triggering an update process.
This can be integrated with your CRM to track content performance (e.g., traffic, engagement metrics) and trigger tasks for content managers or automated updates.
Workflow Steps:
- Performance Monitoring: Regularly pull SEO metrics (e.g., from Google Analytics, Search Console) for key content pages.
- Content Audit Trigger: Define rules to flag content for review (e.g., declining traffic, low engagement, outdated information).
- Content Update Task: Create tasks in your CRM or project management tool for content managers, or trigger automated content modification scripts.
- Automated Republishing: Schedule the republishing of updated content to ensure it’s re-indexed by search engines.
Example Bash Script for Scheduled Content Audit Trigger:
#!/bin/bash
# This script would typically be run via cron.
# It simulates fetching data and triggering an alert/task.
# --- Configuration ---
API_ENDPOINT="https://your-crm-api.com/api/v1/tasks"
AUTH_TOKEN="your_api_token"
CONTENT_DATA_FILE="/path/to/content_performance.csv" # Simulated data source
TRAFFIC_DROP_THRESHOLD=20 # Percentage drop to trigger alert
LAST_REVIEW_DAYS_AGO=180 # Content not reviewed in last 180 days flagged
# --- Simulate fetching content performance data ---
# In a real scenario, this would involve API calls to GA/GSC or a database query.
echo "Simulating fetching content performance data..."
# Example CSV format: url,current_traffic,previous_traffic,last_reviewed_date
# For demonstration, we'll use hardcoded data.
# --- Process Content ---
echo "Analyzing content performance..."
while IFS=',' read -r url current_traffic previous_traffic last_reviewed_date; do
# Skip header row
[[ "$url" == "url" ]] && continue
# Convert traffic to numbers
current_traffic_num=$(echo "$current_traffic" | tr -d ',')
previous_traffic_num=$(echo "$previous_traffic" | tr -d ',')
# Calculate traffic drop percentage
traffic_drop=0
if (( $(echo "$previous_traffic_num > 0" | bc -l) )); then
traffic_drop=$(echo "scale=2; ((${previous_traffic_num} - ${current_traffic_num}) / ${previous_traffic_num}) * 100" | bc)
fi
# Calculate days since last review
days_since_review=0
if [[ -n "$last_reviewed_date" ]]; then
last_reviewed_ts=$(date -d "$last_reviewed_date" +%s)
current_ts=$(date +%s)
days_since_review=$(( (current_ts - last_reviewed_ts) / 86400 ))
fi
# --- Trigger Alerts/Tasks ---
if (( $(echo "$traffic_drop > $TRAFFIC_DROP_THRESHOLD" | bc -l) )); then
echo "ALERT: Significant traffic drop for $url (Drop: ${traffic_drop}%)"
# Create task in CRM
curl -X POST "$API_ENDPOINT" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Review Content: High Traffic Drop - '"$url"'",
"description": "Traffic dropped by '"$traffic_drop"'%. Current: '"$current_traffic"', Previous: '"$previous_traffic"'.",
"priority": "High",
"due_date": "'$(date -d "+7 days" +%Y-%m-%d)'"
}'
elif (( days_since_review > LAST_REVIEW_DAYS_AGO )); then
echo "INFO: Content $url due for review (Last reviewed: $last_reviewed_date)"
# Create task in CRM
curl -X POST "$API_ENDPOINT" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Review Content: Periodic Check - '"$url"'",
"description": "Content has not been reviewed in '"$days_since_review"' days.",
"priority": "Medium",
"due_date": "'$(date -d "+30 days" +%Y-%m-%d)'"
}'
fi
done < <(cat "$CONTENT_DATA_FILE") # Process the file
echo "Content analysis complete."
5. Personalized Product Recommendations via CRM Integration
Leveraging CRM data to personalize the user experience on your e-commerce site can significantly improve engagement and conversion rates, indirectly boosting SEO through better user signals. This involves feeding CRM data (purchase history, browsing behavior, demographics) back to the website to tailor product recommendations.
A common approach is to use a recommendation engine that queries the CRM or a data warehouse populated by the CRM to fetch user profiles and generate personalized product suggestions.
Workflow Steps:
- Data Synchronization: Ensure real-time or near real-time synchronization of customer data between your e-commerce platform and CRM.
- User Profiling: Develop or utilize a system to create rich user profiles based on CRM data.
- Recommendation Engine: Implement a recommendation algorithm (collaborative filtering, content-based, or hybrid) that uses user profiles to suggest products.
- Website Integration: Display personalized recommendations on product pages, category pages, or the homepage.
Example Nginx Configuration Snippet for Serving Recommendation API:
# Assume your recommendation engine is running on port 8080
# and exposes an API endpoint like /recommendations?user_id=XYZ
server {
listen 80;
server_name your-ecommerce-site.com;
# ... other server configurations ...
location /api/recommendations {
# Proxy requests to the recommendation engine
proxy_pass http://127.0.0.1:8080/recommendations; # Assuming engine is on localhost:8080
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Optional: Cache recommendations for anonymous users or for a short period
# proxy_cache_valid 5m;
# proxy_cache_key "$scheme$request_method$host$request_uri";
# add_header X-Cache-Status $upstream_cache_status;
}
# ... other location blocks for your e-commerce site ...
}
6. Automated Customer Segmentation for Targeted Content
Segmenting your audience allows for more targeted content creation and promotion, which can lead to higher engagement and better SEO performance. This workflow automates the process of assigning customers to segments based on their behavior and CRM data.
This can involve rules-based segmentation (e.g., high-value customers, recent purchasers) or more advanced clustering algorithms. The segments can then inform content strategy, email marketing, and even on-site personalization.
Workflow Steps:
- Data Aggregation: Collect relevant customer data from CRM, e-commerce platform, and analytics tools.
- Segmentation Rules/Models: Define criteria for segmentation (e.g., RFM analysis, purchase frequency, product category affinity).
- Automated Assignment: Run a script or use CRM features to assign each customer to one or more segments.
- Content Strategy Alignment: Use segment data to tailor blog topics, product page content, and promotional offers.
Example SQL Query for RFM Segmentation:
WITH CustomerRFM AS (
SELECT
customer_id,
-- Recency: Days since last purchase
JULIANDAY('now') - JULIANDAY(MAX(order_date)) AS Recency,
-- Frequency: Total number of orders
COUNT(DISTINCT order_id) AS Frequency,
-- Monetary: Total amount spent
SUM(total_amount) AS Monetary
FROM orders -- Assuming an 'orders' table with customer_id, order_date, order_id, total_amount
WHERE order_date >= DATE('now', '-365 day') -- Consider orders within the last year
GROUP BY customer_id
),
RFMRank AS (
SELECT
customer_id,
Recency,
Frequency,
Monetary,
-- Rank Recency (lower is better)
NTILE(5) OVER (ORDER BY Recency ASC) AS R_Rank,
-- Rank Frequency (higher is better)
NTILE(5) OVER (ORDER BY Frequency DESC) AS F_Rank,
-- Rank Monetary (higher is better)
NTILE(5) OVER (ORDER BY Monetary DESC) AS M_Rank
FROM CustomerRFM
)
SELECT
r.customer_id,
r.R_Rank,
r.F_Rank,
r.M_Rank,
-- Combine ranks into an RFM score (e.g., concatenate)
CAST(r.R_Rank AS TEXT) || '-' || CAST(r.F_Rank AS TEXT) || '-' || CAST(r.M_Rank AS TEXT) AS RFM_Score,
-- Define segments based on RFM score (example logic)
CASE
WHEN r.R_Rank >= 4 AND r.F_Rank >= 4 AND r.M_Rank >= 4 THEN 'Champions'
WHEN r.R_Rank >= 3 AND r.F_Rank >= 3 THEN 'Loyal Customers'
WHEN r.R_Rank >= 4 AND r.F_Rank <= 2 THEN 'Recent Customers'
WHEN r.R_Rank <= 2 AND r.F_Rank >= 4 THEN 'Cant Lose Them'
WHEN r.R_Rank <= 2 AND r.F_Rank <= 2 THEN 'At Risk'
ELSE 'Others'
END AS CustomerSegment
FROM RFMRank r;
-- This query can be run periodically and the results stored in a 'customer_segments' table.
-- You would then join this table with your customer table for targeted actions.
7. Automated Competitor Monitoring and Gap Analysis
Understanding what competitors are doing well is vital for SEO growth. Automating the monitoring of competitor content, keyword rankings, and backlink profiles can reveal opportunities and threats.
This workflow could involve using SEO tools APIs (like Ahrefs, SEMrush) to fetch competitor data and then analyzing it for keyword gaps, content themes, or link-building opportunities that you can capitalize on.
Workflow Steps:
- Competitor Identification: Maintain a list of key competitors.
- Data Fetching: Use SEO tool APIs to retrieve data on competitor rankings, new backlinks, and top content.
- Gap Analysis: Compare your keyword rankings and content against competitors to identify keywords they rank for that you don’t.
- Opportunity Prioritization: Rank identified opportunities based on search volume, competition, and relevance.
- Actionable Insights: Generate reports or trigger tasks for content creation or optimization.
Example Python Script Snippet (Conceptual using a hypothetical SEO API):
import requests
import pandas as pd
# --- Configuration ---
SEO_API_KEY = "YOUR_SEO_API_KEY"
COMPETITORS = ["competitor1.com", "competitor2.com"]
YOUR_DOMAIN = "your-ecommerce-site.com"
BASE_URL = "https://api.seo-tool.com/v1" # Hypothetical API
def get_competitor_keywords(domain):
"""Fetches top organic keywords for a given domain."""
try:
response = requests.get(f"{BASE_URL}/organic-keywords",
params={"domain": domain, "api_key": SEO_API_KEY, "limit": 1000})
response.raise_for_status() # Raise an exception for bad status codes
data = response.json()
# Assuming response is a list of dicts: [{'keyword': '...', 'rank': N, 'volume': V}, ...]
df = pd.DataFrame(data.get('results', []))
df['domain'] = domain
return df
except requests.exceptions.RequestException as e:
print(f"Error fetching keywords for {domain}: {e}")
return pd.DataFrame()
def get_my_keywords():
"""Fetches your site's organic keywords."""
try:
response = requests.get(f"{BASE_URL}/organic-keywords",
params={"domain": YOUR_DOMAIN, "api_key": SEO_API_KEY, "limit": 5000})
response.raise_for_status()
data = response.json()
df = pd.DataFrame(data.get('results', []))
df['domain'] = YOUR_DOMAIN
return df
except requests.exceptions.RequestException as e:
print(f"Error fetching keywords for {YOUR_DOMAIN}: {e}")
return pd.DataFrame()
# --- Main Logic ---
all_competitor_keywords = []
for comp_domain in COMPETITORS:
print(f"Fetching keywords for {comp_domain}...")
comp_df = get_competitor_keywords(comp_domain)
if not comp_df.empty:
all_competitor_keywords.append(comp_df)
if not all_competitor_keywords:
print("No competitor keyword data fetched. Exiting.")
exit()
competitor_keywords_df = pd.concat(all_competitor_keywords, ignore_index=True)
my_keywords_df = get_my_keywords()
# --- Gap Analysis ---
print("Performing gap analysis...")
# Get keywords competitors rank for, but you don't (or rank poorly)
competitor_keywords_set = set(competitor_keywords_df['keyword'].unique())
my_keywords_set = set(my_keywords_df['keyword'].unique())
# Keywords competitors rank for
competitor_only_keywords = competitor_keywords_set - my_keywords_set
# Filter for keywords with decent search volume (example: > 100 searches/month)
competitor_only_df = competitor_keywords_df[
competitor_keywords_df['keyword'].isin(competitor_only_keywords) &
(competitor_keywords_df['volume'] > 100)
]
# Find top competitors for each gap keyword
gap_analysis_results = competitor_only_df.groupby('keyword').agg(
total_competitors=('domain', 'nunique'),
avg_rank=('rank', 'mean'),
avg_volume=('volume', 'mean')
).reset_index()
# Sort by number of competitors and average rank
gap_analysis_results = gap_analysis_results.sort_values(by=['total_competitors', 'avg_rank'], ascending=[False, True])
print("\n--- Keyword Gap Analysis Results ---")
print(gap_analysis_results.head(20)) # Display top 20 opportunities
# In a real system, you would:
# - Store these results in a database.
# - Create tasks for content teams to target these keywords.
# - Integrate with a CMS to suggest content ideas.
8. Automated Link Reclamation Workflow
Broken backlinks (links from other sites pointing to pages on your site that no longer exist or have changed URLs) represent lost link equity and potential traffic. Automating the identification and reclamation of these links is a powerful SEO tactic.
This workflow involves regularly checking your backlink profile (via tools like Ahrefs, SEMrush, or Google Search Console) for 404 errors and then reaching out to the linking sites to request a fix or redirect.
Workflow Steps:
- Backlink Monitoring: Regularly fetch your backlink data, focusing on pages returning 404 errors.
- Broken Link Identification: Filter for backlinks pointing to URLs that result in a 404 status code.
- Linking Page Analysis: Identify the referring page and anchor text used.
- Outreach Preparation: Compile a list of broken backlinks and the corresponding linking sites/pages.
- Automated Outreach (Optional): Integrate with email marketing tools or CRM to send personalized outreach emails requesting a URL update or redirect.
Example Python Script Snippet (Conceptual using GSC API & requests):
import requests
import pandas as pd
from googleapiclient.discovery import build
from google.oauth2 import service_account
import datetime
# --- Configuration ---
# Replace with your Google Cloud Project Service Account credentials
SERVICE_ACCOUNT_FILE = 'path/to/your/service_account.json'
SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']
PROPERTY_URI = 'https://your-ecommerce-site.com/' # Your GSC property URI
# --- Authentication ---
try:
creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('searchconsole', 'v1', credentials=creds)
except Exception as e:
print(f"Error authenticating with Google Search Console: {e}")
exit()
def get_gsc_data(start_date, end_date, dimension='page', search_type='web'):
"""Fetches data from Google Search Console."""
try:
request_body = {
'startDate': start_date.strftime('%Y-%m-%d'),
'endDate': end_date.strftime('%Y-%m-%d'),
'dimensions': dimension,
'searchType': search_type,
'rowLimit': 5000 # Adjust as needed
}
response = service.properties().searchAnalytics().query(
siteUrl=PROPERTY_URI, body=request_body).execute()
return response
except Exception as e:
print(f"Error querying GSC API: {e}")
return None
def find_broken_backlinks(gsc_data):
"""
Analyzes GSC data to identify pages with potential broken backlinks.
GSC doesn't directly report broken backlinks. This is a proxy:
Look for pages that used to receive clicks