Back to Tools

Link Quality Analyser

Use cases

Broken link detection Spammy anchor text patterns Internal linking audits Content quality assessment

BeautifulSoup CSS selector link extraction with urljoin URL normalisation.

Caches status code results to avoid duplicate requests.

Flags high-frequency anchor text (>3 occurrences) as potentially spammy.

Optional textstat Flesch reading scores.

Filters mailto/tel/javascript protocols and skips any href containing #; image and PDF extensions are filtered only when building the URL list from an XML sitemap.

Streamlit App

Platform

Browser-based (no installation required)

Input

XML sitemap URL (auto-fetches child sitemaps)

CSV with URL column

Or paste URLs directly (one per line)

Content CSS selector (default: body)

Output

CSVs: all links (source, anchor, destination, status, internal flag), page stats (H1, link counts, Flesch score). Anchor frequency table, status distribution, broken links view.

Launch App View Source

Features

  • BeautifulSoup CSS selector link extraction
  • urljoin URL normalisation
  • Skips mailto, tel, javascript and any href containing #
  • Status checks without following redirects, cached per unique URL
  • High-frequency anchor text flagging (>3 uses on a single page)
  • Optional textstat Flesch reading scores (pages over 50 words)
  • Request delay (0.5-5s), timeout (5-60s), max URLs (1-1000)

How to use

  1. 1 Enter URLs via sitemap, CSV, or paste
  2. 2 Set content CSS selector to scope link extraction
  3. 3 Configure delay (0.5-5s), timeout (5-60s), max URLs (1-1000)
  4. 4 Enable HTTP status checking and reading score toggles
  5. 5 Run analysis
  6. 6 Download all links and page stats CSVs

Frequently asked questions

Why are some links on my pages missing from the results?
Any href containing a hash character is skipped, which removes in-page jump links but also removes real URLs that merely carry a fragment (example.com/page#reviews). Links using mailto:, tel: or javascript: are skipped too. If the content selector does not match anything on a page, no links at all are extracted from it.
Why are links to my own site flagged as external?
Internal versus external is decided by comparing hostnames as exact strings. Links to the www variant from a non-www page, or to any subdomain, count as external. If your site mixes hostname formats, expect internal counts to be understated.
How are redirects and errors reported in the status check?
Status requests are made with redirects disabled, so a 301 or 302 is reported as that code, not the final destination's status. The Broken Links view only includes codes starting with 4; server errors (5xx), timeouts and connection errors appear in the status breakdown as their own values but are not counted in the broken links metric. Each unique URL is only requested once thanks to a status cache, with a pause of half your configured delay between checks.
Why is the Flesch reading score blank for some pages?
Scores require the optional textstat package to be installed, and are only calculated when the selected content area contains more than 50 words of text. Short pages, or a content selector that matches a small element, produce no score.
Should I keep the default 'body' content selector?
Usually not. With body, navigation, footer and sidebar links are included on every page, which inflates link counts and makes the spam flag (the same anchor text appearing more than 3 times on one page) fire on ordinary menus. Scope it to your main content element, such as article, main or a template-specific class.

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