MODRACXKENNETH D'SILVA

← Archive & Insights

Advanced Keyword Research for E-Commerce: Intent Clustering

The ultimate guide to commercial intent mapping, semantic topic clustering, TF-IDF vectorization, and automated Search Console data mining using Python.

By Kenneth D'SilvaReading Time: 22 min readCategory: SEO & Marketing

Introduction: Beyond Search Volume

Keyword research has historically been dominated by a singular, fatal metric: search volume. For an ecommerce architect scaling systems across global regions, relying exclusively on search volume is akin to assessing server architecture purely by bandwidth capacity—without analyzing what data actually passes through the pipes. The truth is, raw keyword volume rarely dictates profitability, and in my experience architecting frameworks and optimizing catalogs, targeting the right intent is everything.

As an ecommerce specialist, I often see massive catalogs where every product variant page attempts to rank for generic, high-volume keywords. This strategy creates widespread keyword cannibalization and degrades topical authority. Instead of building organic moats, merchants are building leaky vessels. To counter this, we need a robust, programmatic approach to keyword research—one that leverages intent clustering, vector embeddings, and TF-IDF extraction. In this guide, we explore exactly how to automate keyword research and map commercial search intent using Python.

1. The Four Pillars of E-Commerce Search Intent

Search intent mapping shifts our perspective from what the user types to what the user expects. In ecommerce, these fall into four distinct architectural buckets. Understanding these is the precursor to designing an effective data schema.

  • Transactional Intent: Bottom-of-the-funnel queries. Examples like "buy Goodyear welted boot discount" demand immediate routing to Product Detail Pages (PDPs). Any friction here destroys conversion rates.
  • Commercial Investigation Intent: The user is evaluating options before purchase. Queries such as "best waterproof leather work boots" map perfectly to categorized facets or structured PLPs.
  • Informational Intent: Upper-funnel research. Queries like "how to clean full grain leather boots" should be captured by long-form pillar articles and editorial blog posts, lifting transactional pages via internal link equity.
  • Navigational Intent: Brand-specific queries. Searches for "Modracx leather boots returns" must surface customer support, policy, and brand-specific nodes.

For more on why structure fundamentally impacts visibility, I strongly recommend reviewing my guide on Core Web Vitals and secure ecommerce architectures.

2. Moving Past Manual Spreadsheets

At scale, manually triaging keyword lists in spreadsheets becomes a tragic misuse of engineering resources. When dealing with catalogs containing thousands of SKUs, manual tagging breaks down. We need algorithmic grouping.

By extracting Search Console data, we can apply NLP to cluster terms mathematically based on semantic proximity. A cluster might represent 150 different long-tail queries that all satisfy the exact same user intent. Instead of building 150 thin pages, you deploy one comprehensive category page.

3. Python Script for Automated Data Extraction

Before we can cluster anything, we need precise SERP data. Google’s algorithms are highly sensitive to intent. If two keywords share identical ranking URLs, they share the same search intent. We can automate this extraction using Python.

import requests
from bs4 import BeautifulSoup
import time
import random
import pandas as pd

def parse_serp_intent(keyword):
    """
    Extracts the top 10 organic URLs from Google Search.
    """
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36'
    }
    url = f"https://www.google.com/search?q={keyword.replace(' ', '+')}&num=10"
    
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, 'html.parser')
        
        organic_results = []
        for g in soup.find_all('div', class_='g'):
            link = g.find('a')['href'] if g.find('a') else ''
            title = g.find('h3').text if g.find('h3') else ''
            if link and title:
                organic_results.append({'title': title, 'url': link})
            
        return organic_results
    except Exception as e:
        print(f"Error parsing {keyword}: {e}")
        return []

# Example batch processing
queries = ["leather boots", "buy leather boots online"]
results = []
for q in queries:
    serp_data = parse_serp_intent(q)
    results.append({'keyword': q, 'serp': serp_data})
    time.sleep(random.uniform(2, 5)) 

df_serps = pd.DataFrame(results)
print(df_serps.head())

4. BM25 Term Extraction and Semantic Relevance

Once you have identified the target clusters, the next architectural challenge is ensuring your page content mathematically satisfies the intent. BM25 (Best Matching 25) improves upon traditional TF-IDF by penalizing excessive keyword stuffing and normalizing for document length.

from rank_bm25 import BM25Okapi
import nltk
from nltk.tokenize import word_tokenize
nltk.download('punkt', quiet=True)

competitor_docs = [
    "Shop the best leather work boots online. Waterproof, comfortable, and featuring steel toe protection."
]
tokenized_corpus = [word_tokenize(doc.lower()) for doc in competitor_docs]
bm25 = BM25Okapi(tokenized_corpus)

query = "waterproof leather boots"
tokenized_query = word_tokenize(query.lower())
doc_scores = bm25.get_scores(tokenized_query)
print(f"Document Score: {doc_scores[0]:.4f}")

By extracting the highest-scoring terms, you build a semantic map of entities required for your product page. For decoupled architectures, review my thoughts on headless architecture and edge-rendering optimization.

5. Vector Embeddings with SentenceTransformers for Semantic Understanding

While BM25 is excellent for exact lexical matching and determining term significance within a corpus, it falls short when dealing with synonyms or complex semantic nuance (e.g., "sneakers" vs. "running shoes"). To capture the true meaning behind a search query, we must map keywords into a high-dimensional vector space using transformer models. By generating vector embeddings, we can cluster keywords based on their contextual meaning, even if they share zero overlapping words.

Using the SentenceTransformers library, we can leverage pre-trained models like MiniLM to compute dense vector representations of our Search Console queries. We then apply clustering algorithms, such as Agglomerative Clustering, to group these vectors based on cosine similarity or Euclidean distance.

from sentence_transformers import SentenceTransformer
from sklearn.cluster import AgglomerativeClustering
import numpy as np

# Load an efficient, pre-trained sentence transformer model optimized for semantic similarity
model = SentenceTransformer('all-MiniLM-L6-v2')

# Raw search queries extracted from Google Search Console
keywords = [
    "buy running shoes",
    "best sneakers for jogging",
    "discount marathon footwear",
    "how to train for a 5k",
    "5k training plan for beginners",
    "what to eat before running",
    "best diet for long distance runners"
]

print("Generating high-dimensional vector embeddings...")
# Generate dense vector embeddings for the keyword list
embeddings = model.encode(keywords)

# Perform hierarchical clustering on the embeddings
# The distance_threshold determines the granularity of the clusters
clustering_model = AgglomerativeClustering(n_clusters=None, distance_threshold=1.5, metric='euclidean', linkage='ward')
clustering_model.fit(embeddings)
labels = clustering_model.labels_

# Group the original keywords by their assigned cluster label
clustered_data = {}
for keyword, label in zip(keywords, labels):
    if label not in clustered_data:
        clustered_data[label] = []
    clustered_data[label].append(keyword)

print("\nSemantic Keyword Clusters:")
for cluster_id, terms in clustered_data.items():
    print(f"Cluster {cluster_id}: {', '.join(terms)}")

Notice how "buy running shoes" and "discount marathon footwear" map to the same cluster despite lacking lexical overlap. This is the power of vector embeddings. They understand the underlying intent and contextual similarity. When integrated into your data pipelines, this script can process 100,000 queries in minutes, delivering a perfectly grouped content strategy that dictates the exact taxonomy of your ecommerce store.

6. Automating Keyword Cannibalization Audits

One of the most insidious architectural flaws is keyword cannibalization—where multiple URLs compete for the same keyword. We can write an auditing script that cross-references Search Console data with our site architecture to detect conflicting URLs.

import pandas as pd

data = {
    'query': ['mens work boots', 'mens work boots'],
    'url': ['/category/work-boots/', '/product/boot-x/'],
    'clicks': [800, 20]
}
df_gsc = pd.DataFrame(data)

cannibalization_check = df_gsc.groupby('query').agg(
    url_count=('url', 'nunique'),
    total_clicks=('clicks', 'sum'),
    urls=('url', lambda x: list(x))
).reset_index()

cannibalized_queries = cannibalization_check[cannibalization_check['url_count'] > 1]
print(cannibalized_queries)

The resolution involves aggressive URL consolidation, strict canonicalization, and internal link restructuring to point definitively to the primary page, aided by robust technical SEO and structured data.

6. Architecting the Ideal Taxonomy

The root of the taxonomy should be defined by the most generic transactional clusters (e.g., /boots/). The child nodes represent secondary intent modifiers (e.g., /boots/work/). The leaf nodes represent hyper-specific long-tail clusters (e.g., /boots/work/waterproof-steel-toe/).

This structure creates natural breadcrumb trails. When implemented with JSON-LD schema markup, these breadcrumbs provide unambiguous signals to the crawler regarding the hierarchical relationship of the clusters.

8. Advanced Log File Analysis for Cluster Validation

While SERP data and vector embeddings provide the theoretical blueprint for intent clustering, log file analysis provides the empirical validation. By parsing server logs (Nginx or Apache), we can observe exactly how search engine bots are interacting with our newly clustered architecture. If we deploy a new category page designed to capture a high-value transactional cluster, but the log files reveal that Googlebot is ignoring the URL while aggressively crawling parameterized facet pages, we know our internal linking or canonicalization strategy has failed.

To automate this, we can write a Python script using Regex and Pandas to parse raw Nginx logs, filter for Googlebot user-agents, and aggregate crawl frequency against our URL clusters. This feedback loop is essential for enterprise SEO.

import pandas as pd
import re

# Regex pattern for standard Nginx combined log format
log_pattern = re.compile(
    r'(?P\\S+) \\S+ \\S+ \\[(?P

9. Conclusion: Scalable Systems

Enterprise keyword research is fundamentally a data engineering challenge. By utilizing Python, clustering algorithms, and programmatic audits, you construct an SEO architecture rooted in mathematical precision. This methodology future-proofs your catalog against algorithmic volatility and aligns perfectly with modern search intent. If you're looking into improving speed as well, see my guide on performance optimization.

Frequently Asked Questions (FAQ)

1. What is Keyword Intent Clustering?

Keyword Intent Clustering groups semantically related search terms into thematic clusters based on shared SERP search results. By targeting a cluster of 50 long-tail terms on a single category page, e-commerce stores build topical authority without cannibalization.

2. How does BM25 scoring improve on-page relevance?

BM25 normalizes for document length and penalizes keyword stuffing. It provides an algorithmic representation of which entities are required to satisfy the semantic expectations of the search engine.