Back to Tools

Internal Search Mapper

Use cases

Identifying products or content users search for but cannot find Improving internal site search by adding redirects Planning new landing pages based on user demand Understanding user intent and terminology

Matches GA internal search queries to page H1s using TF-IDF fuzzy matching via PolyFuzz.

Outputs exact matches (similarity 1.0) and partial matches ranked by relevance and search volume.

Filters non-indexable pages and deduplicates queries keeping highest-value instances.

Streamlit App

Platform

Browser-based (no installation required)

Input

GA internal search export

Screaming Frog crawl CSV

Output

CSVs with exact and partial search matches

Launch App View Source

Features

  • TF-IDF fuzzy matching via PolyFuzz library
  • Exact and partial match separation (similarity scores)
  • Automatic non-indexable page filtering
  • Deduplication keeping highest search volume instances
  • Results sorted by Total Unique Searches

How to use

  1. 1 Export GA internal search report as Excel
  2. 2 Export Screaming Frog crawl with H1 and indexability columns
  3. 3 Upload both files to the tool
  4. 4 Run TF-IDF matching against indexable page H1s
  5. 5 Download three CSVs: exact matches, partial matches, and combined results

Frequently asked questions

What exact export formats does it expect?
Two files: the Google Analytics site search terms report as Excel (the script reads a sheet named Dataset1; the Streamlit app falls back to the first sheet if that name is missing), and a Screaming Frog crawl CSV. The script needs the columns H1-1, Address and Indexability from internal_html.csv; the app lets you map any search term, H1 and URL columns from dropdowns.
Does this work with GA4?
It was built around the Universal Analytics Behavior > Site Search > Search Terms export, and the script hardcodes UA column names like Search Term and Total Unique Searches. In the Streamlit app you can map any column as the search term, so a GA4 view_search_results export works if you shape it into a spreadsheet first, but the volume-based sorting only kicks in if a column name contains 'search' plus 'unique' or 'volume'.
What does it actually match against?
Page H1s only, not URLs or title tags. Search terms and H1s are lowercased and matched with PolyFuzz TF-IDF, and each search term gets exactly one best-matching H1. The readme recommends crawling just your category pages, otherwise terms will happily map to blog posts or product pages.
How are non-indexable pages excluded?
Rows where the Indexability column equals exactly 'Non-Indexable' are dropped before matching. If your crawl export lacks that column (the app skips the filter silently in that case) or uses different wording, non-indexable URLs will appear as match targets.
Why do some search terms disappear from the results?
Duplicates are removed keeping one row per search term, and results are deduplicated after sorting by search volume so the highest-volume instance survives. In the app there is also a minimum similarity slider (default 0.5), so terms whose best H1 match scores below the threshold are filtered out entirely; lower the slider to see them.

Need something built for your business?

This tool started as bespoke client work. I build custom scripts, data pipelines, and full apps for SEO and product data problems that off-the-shelf tools don't solve.

Tell Me What You Need