URL understanding @ Contentsquare · 2021 – 2024

Auto-mapping

Proposing a website's page groups, their rules
and their page categories, straight from its URLs.

URLs + views inpage groups + rules outhuman in the loopSlim Frikha
The product problem

Every website needs a mapping

Reference mapping HOMECATEGORYPRODUCT CARTCONFIRMATIONMY ACCOUNT Page categories Home Category Top categories Offers Product page Product page (add to bag) Shopping cart Order confirmation Profile Page groups Product page Batch 1 Path contains "/product/" AND Query does not contain "cs-popin-add-to-bag" Rules

A mapping = a set of page groups

Each page group gathers similar pages, is built with rules on the URL, and is assigned a page category.

Rules use the product's operators

contains, does not contain, exactly matches, begins with, ends with, regex… on the path, the query or custom variables, combined with AND / OR.

Why it matters: a mapping is the logical view of a site that analyses build on: journey analysis, and any automatic analysis that needs page context.

Auto-mappingProduct problem
The product problem

Mapping by hand doesn't scale

Set up the mapping Group URLs to create pages Path▾ contains▾ /product/ 1 2 3 URLs not included (12,000) /en/product/oak-desk-a1048 /en/product/linen-sofa-a2213 /en/product/wall-shelf-a3390 /en/product/floor-lamp-a4127 /en/product/side-table-a5562 /en/product/bed-frame-a6031 1,2001,100950900860800 Create a new page product page Product▾ 4 5 Create

Today (sketch): pick a URL part ①, an operator ②, a value ③, check the matched URLs, name the page group ④ and pick its category ⑤. Repeat for every group, on every website.

Creating a mapping is:

1

Too manual: every rule is written by a person.

2

Cumbersome and hard to learn.

3

Time-consuming, group after group.

4

A human bottleneck for every feature that depends on mappings.

Task 1Create meaningful page groups (clusters)

Task 2Determine the conditions that build each group

Task 3Determine each group's page category

Auto-mappingProduct problem
The product problem · Data

Reference mappings as ground truth

467

websites with a reference mapping

16

page categories

1,000

URLs sampled per website, half weighted by traffic

~650

curated important terms

One URL, four parts, and its terms

# a URL with its custom variables after || url = "shop.example/gb/en/?utm_content=6578sd&id=7766||logged<true~pagetype<home" host shop.example path levels = ['gb', 'en'] query keys = ['utm_content', 'id'] values = ['6578sd', '7766'] cvars keys = ['logged', 'pagetype'] values = ['true', 'home'] terms = ['gb', 'en', 'utm_content', 'id', 'logged', 'pagetype']

Each URL comes with its views, its reference page group, that group's rules and page category. Mappings are kept when they are clean: enough URLs and categories, few URLs matching two groups, most traffic mapped.

Auto-mappingData
The product problem · Data

Thousands of URLs, but one set of templates per website

shop-a.examplepath-based /fr/product/oak-desk-a1048/fr/product/pine-shelf-a2213 /fr/product/sofa-bed-a3390/fr/c/bedroom /fr/c/kitchen/fr/search?q=sofa… thousands more /fr/product/{slug}-{id} /fr/c/{name} /fr/search?q=* shop-b.examplequery + custom variables /index?page=item&id=123||type<product/index?page=item&id=987||type<product /index?page=list&cat=12||type<category/index?page=list&cat=40||type<category /index?page=basket||type<cart… thousands more page=item · type=product page=list · type=category page=basket · type=cart
1

Variability lives between websites. URL design, naming, language and rule style are set per site.

2

More URLs of a known site add little. They mostly repeat its templates with new IDs: 1,000 URLs per site are enough.

3

Split by website. Train, validation and test websites are kept apart, so scores measure sites the system has never seen.

4

Progress comes from new websites. Each newly mapped site brings new terms and conventions.

Auto-mappingData variability
The modeling solution · Design choices

Two choices that shape the solution

Choice 1

Cluster, then describe

Group similar URLs without labels, then write rules for each group. The output has the shape of a mapping: groups, rules, categories.

A first attempt classified single URLs into page categories with a character-level CNN over path, query and custom variables. It performed poorly on several categories, and a per-URL label gives neither groups nor rules.

Choice 2

Measure against human mappings

Clustering becomes a pairwise classification: for each pair of URLs, are they in the same reference page group, and in the same proposed group?

per website w: F1w = ½ (F1same + F1different)
score = mean of F1w over validation websites

Validation websites are never used to build anything, so the score measures websites the system has never seen.

Auto-mappingDesign choices
The modeling solution · First version

First version: a plain URL distance and a silhouette cut

1

Sample 1,000 URLs per website.

2

Distance, field by field: same host? same value at each path level? how many shared query and custom-variable keys, with equal values? Normalized over levels, keys and URL parts, bounded in [0, 1]. Every term weighs the same.

3

Hierarchical clustering builds a tree (a dendrogram) over the URLs.

4

Cut the tree: try every number of clusters between 10 and 40, and keep the one with the best silhouette score.

5

Write rules for each cluster.

Pairwise macro F1
63.5%

± 10.8% across websites

Validation websites

Auto-mappingFirst version
The modeling solution · First version

Why the first version breaks

first split: en | fr silhouette cut /en//en//en//en/ /fr//fr//fr//fr/ productproductcartsearch productproductcartsearch product, en onlycart + searchproduct, fr onlycart + search

Illustrative tree: the cut gives product groups split by locale, and groups mixing page types.

The distance is blind to meaning

A match on an ID or a locale counts as much as a match on product. For example, two product URLs are 0.21 apart, and a product and a cart only 0.43.

The cut is blind to meaning

The number of clusters comes from the silhouette score, a geometric criterion. The splits that matter, like product versus cart, can sit anywhere in the tree, even at the very bottom: groups come out fragmented, or mixing page types.

Both need to know which terms matter: the second version adds a term library.

Auto-mappingFirst version
The modeling solution · Second version

Second version: add a term library

Sample1,000 URLs + views Important termsmatch the library Weighted distanceN × N matrix Hierarchicalclustering Cut the treewhere terms define groups Rules + categoryper page group dendrogram Person (Term Builder)confirms the terms term library Clusters screenperson reviews, saves new new new

Unsupervised: no labels at prediction time, one run per website.

Guided by the term library and by the person's choice of terms.

Explainable: every group comes with rules and the terms behind it.

Auto-mappingSolution overview
Modeling deep dive · 1 Important terms

A curated library of terms that carry meaning

Most frequent path terms in the library

termwebsitesvalidpage category
search151yessearch
checkout138yescheckout
login116yesform
cart97yescart
account86yesmy_account
contact72yeshelp_support
faq53yeshelp_support

Three lists: path (302 terms), query (240), custom variables (109).

Build the library

1

Extract the terms used in the rules of reference mappings, from training websites only.

2

Annotate their importance by hand, with a page category when it is clear. The flywheel keeps adding terms (slide 17).

For a new website

3

Extract its distinct terms, with their share of URLs and traffic.

4

A term is important if it is very similar to a library term (Levenshtein ratio > 0.8). It inherits that term's category.

5

Terms on more than 95% of URLs lose their importance: they can't tell groups apart.

Auto-mappingDeep dive · terms
Modeling deep dive · 2 Weighted distance

Weighting aligns the distance with business needs

d(a, b) = 1 − Σpart Wpart · Spart(a, b) / Σ Wpart
parts: host · path · query · custom variables
1

Field by field: same host? same value at each path level? how many shared keys, with equal values?

2

Term weights: an important term weighs 0.9, any other 0.1, so matching on product counts 9× more than matching on an ID.

3

Part weights come from the traffic of each part's important terms. The host gets half of the smallest.

4

Bounded in [0, 1]. The full N × N matrix is computed in Rust.

Distance between example URLs product_1 vs product_2same template product_1 vs cartdifferent page types host only vs product_1nothing in common 0.21 0.07 0.43 0.74 0.86 1.00 first version with important-term weighting

URLs like shop.example/products/1234?some_key=toto||c_key<c_value~page_category<product; important terms: path products, cart; custom variable page_category.

Auto-mappingDeep dive · distance
Modeling deep dive · 3 Weighting and the tree

Weighting lifts important terms to the top of the tree

Without weighting · first version

en | fr /en/product/en/cart/en/search /fr/product/fr/cart/fr/search Nodes defined by one important term exist only at the bottom

With weighting · second version

productcartsearch start here /en/product/fr/product/en/cart /fr/cart/en/search/fr/search One node per page type, right below the root

Merged last. Two URLs that differ on an important term are far apart, so they merge late: the split on that term sits near the root.

Met first. Walking down from the root, the cut reaches nodes defined by an important term before any noise split, and stops there.

Not guaranteed before. Without weighting, such nodes can sit at the bottom of the tree, and the groups come out fragmented or meaningless.

Auto-mappingDeep dive · weighting and the tree
Modeling deep dive · 4 Tree cut

Cut the tree where important terms define a group

1 · Flag nodes whose rules contain an important term with a single value, e.g. level 1 = cart.

2 · Walk down from the root and stop at important nodes. Branches with none collapse to their highest node.

3 · Select the stopping nodes as page groups: two important ones and one catch-all.

important not important collapsed / ignored selected page group Size guards: > 1 URL or 0.5% traffic, and < 80%.
Auto-mappingDeep dive · tree cut
Modeling deep dive · 5 Rules and category

Describe each group with rules, then label it

Positive and negative conditions

URLs in the group/product/12345 · /product/98761 · /product/55002
Look-alike outside/product/compare?ids=1,2
positivewhat every URL shares: host = shop.example, level 1 = product, level 2 = any
negativewhat excludes the look-alikes: level 2 ≠ compare

Main idea: if a field takes few distinct values in the group, those values become a condition; if it takes many, it becomes a wildcard. An in-house library, autoconda, does this.

Translated into product rules

Path contains "/product/" AND Path does not contain "/compare"

A translation layer turns the conditions into the product's operators. Illustrative example.

Page category: a vote

Collect the categories of the important terms in the group's rules. One category: the group gets it. Several or none: left for the person to choose.

Auto-mappingDeep dive · rules
Evaluation

Second version: from 63.5% to 87.4%

What changed between the two versions

First versionSecond version
Term importancenoneinherited from the curated library
Distanceevery term weighs the sameimportant terms 9×, part weights from traffic
Cutnumber of clusters by silhouettewalk down to nodes defined by an important term
63.5%

± 10.8%
first version

87.4%

± 12.2%
second version

What the gap shows

Using term importance, in the distance and in the cut, fixes both failures of the first version (slide 8): the distance and the tree now follow business meaning.

The remaining errors

Come mostly from imperfect importance inheritance, which the person fixes in the Term Builder.

Pairwise macro F1 · validation websites · ± across websites.

Auto-mappingEvaluation
From model to product

The person in the loop: two screens

Term Builder× PATHQUERYCVARS termurlstraffic en99.8%99.9% store97.0%98.0% category18.0%26.0% basket1.0%15.0% Apply

Term Builder: important terms are pre-checked; the person keeps or changes them. Values of a key can be listed too.

Clusters× ConditionTrafficURLs (Host: shop.example) AND (Path: level 1=/en/ AND level 2=/category/) AND (Cvars: page_type=product listing) 26.0%18.0% (Host: shop.example) AND (Path: level 1=/en/ AND level 2=/order/) AND (Cvars: step=delivery OR payment OR confirmation) (Host: shop.example) AND (Cvars: page_type=home page) View non important clusters ▾ Back

Clusters: proposed groups with their rules (important parts highlighted), traffic and URL share. Groups without an important rule are folded away.

Auto-mappingProduct
From model to product

A data flywheel

Auto-mapping proposespage groups and rules A person refinesterms, groups, categories More qualitative mappingson more websites Terms join the libraryfrom training websites less human input over time
1

Auto-mapping proposes a mapping for a new website.

2

A person refines it and saves it: a new, qualitative mapping.

3

The terms used in its rules are parsed and added to the library, keeping the train / validation / test split by website.

4

New websites bring new terms and conventions, so the next proposals need less correction.

Variability comes from new websites, so the system improves by being used on more of them.

Auto-mappingFlywheel
From prediction to product

Serving: one stateless API

1

Validate the payload and parse each URL into host, path, query and custom variables (urldata).

2

Score terms against the library; take the person's important terms.

3

Distance matrix in Rust, Ward clustering in SciPy, important-term cut.

4

Rules from autoconda, category vote; return each group with its rules, traffic and URL share, a sample URL and its category.

POST /v1/get_terms URLs → terms + importance POST /v1/get_clusters URLs + terms → page groups POST /v1/get_key_values URLs + key → its values

No weights, no database

The "model" is code plus the curated term library. FastAPI service in one Docker image; Python 3.11 with a Rust extension.

Release with GitOps

Two-stage image build (Rust wheel, then Python) → Harbor registry → version set in the infra repo → ArgoCD.

Five environments

staging · AWS eu-west-1AWS eu-west-1AWS us-east-1Azure eastus2Azure northeurope
Auto-mappingServing
Recap

Auto-mapping in four ideas

1

An important-term prior

A curated library says which URL terms carry business meaning.

2

A weighted URL distance

Field by field, with important terms weighing 9× more.

3

A tree cut driven by importance

Weighting puts important-term nodes near the root, so walking down from the root stops on them.

4

Positive and negative rules

Readable conditions per group, translated into product rules.

And a data flywheel: every refined mapping adds terms, and every new website makes the next proposal better.

Auto-mappingThank you · questions
Sources

To go further

Auto-mappingSources
← → navigate · F fullscreen