URL Extractor

Paste text, HTML, a chat export or a log and every link in it comes back as a CSV. Tracking parameters are removed before the deduplication runs, which is the order that actually collapses six campaign variants of one article into one row. Bare www. hosts, mailto: and tel: links are all found.

No text to hand? Try an example loads a realistic set of links, tracking parameters and all.

Strip first, then deduplicate. The order is the whole trick

A marketing team posts one article six times. Each post carries a different utm_source, and two of them also carry a utm_campaign. A seventh copy arrives from somebody who pasted the clean link. To a string comparison those are seven distinct URLs, so a tool that deduplicates first removes nothing at all, and you are left doing the work by eye.

Strip the tracking parameters first and the same seven collapse to one:

https://example.com/blog/release-4-2?utm_source=newsletter&utm_medium=email&utm_campaign=july
https://example.com/blog/release-4-2?utm_source=twitter
https://example.com/blog/release-4-2

  becomes

https://example.com/blog/release-4-2

The list of stripped parameters is explicit, not a prefix rule. That matters: ref means "referrer" on some sites and "reference number" on others, and id is nearly always load-bearing. Everything on the list is unambiguously a campaign tag or a click identifier: the utm_ family, gclid, gbraid, wbraid, dclid, fbclid, msclkid, twclid, yclid, ttclid, igshid, mc_cid, mc_eid, mkt_tok, _hsenc, the Matomo and Piwik pairs, and a couple of dozen more. Whatever it removed is named in the note above the table, so you can see it happened.

Knowing where a URL ends

A URL in running prose is followed by punctuation that belongs to the sentence, and a pattern greedy enough to capture query strings will swallow it. Trimming trailing punctuation is the obvious fix and it is wrong in one specific, common case.

  • See https://example.com/a.: the full stop is the sentence's. Trim it.
  • (see https://example.com/a): the closing bracket is the sentence's. Trim it.
  • https://en.wikipedia.org/wiki/Ada_(programmer): the closing bracket is part of the URL. Trimming it gives a link that 404s, and Wikipedia links are one of the most common things in a link dump.

So the trimming counts brackets. A closing bracket with no matching opening bracket inside the URL came from the prose around it and is removed; one that has a partner is kept. Full stops, commas, semicolons, colons, exclamation marks and quotes are always trimmed, because none of them can legally end a URL.

Bare www.example.com is picked up too and given the https:// it was written without, because that is how half of all prose writes a link and skipping them means missing half the answer.

Worked example: nine matches, five rows

The sample text holds nine link-shaped runs. With the defaults on, five rows come out.

url
https://example.com/blog/release-4-2
http://exmpl.co/r42
https://docs.example.com/guide/getting-started#install
https://en.wikipedia.org/wiki/Ada_(programmer)
https://www.example.org/about
ftp://mirror.example.net/pub/release-4.2.tar.gz
mailto:support@example.com
tel:+442079460018

The Wikipedia bracket survived. The fragment #install survived, because a fragment identifies a section and removing it would point at a different place on the page. The three campaign variants of the release post became one. And mailto: and tel: are in there, which most extractors miss entirely because their pattern demands a :// that neither scheme has.

Set Keep to http and https only and the last three drop out with the count reported. Set it to https only and the plain-http short link goes too. Tick Domain column and you get a second column reading example.com, exmpl.co, docs.example.com and so on, with any www. prefix removed so that www.example.org and example.org group together.

What normalization does to your links

Parsing and re-serializing a URL changes it slightly, and every change is one that helps deduplication find genuine repeats:

  • The host is lowercased. HTTPS://Example.COM/a and https://example.com/a are the same page and now the same string.
  • A bare origin gains a trailing slash. https://example.com becomes https://example.com/, which is what the server sees either way.
  • Percent-encoding is normalized to the canonical form.
  • The remaining query parameters keep their order and their values. Only the tracking ones are removed, and only when the option is on.

If you need the links byte for byte as they were written, turn Strip tracking parameters off. The host lowercasing and the trailing slash still happen, because they are properties of the URL rather than edits to it, and no destination distinguishes them.

Things people use this for

  • Auditing a newsletter before it goes out. Paste the rendered HTML, get every link, check the domains column for anything you did not expect.
  • Cleaning a research bookmark dump. A month of saved links arrives full of campaign tags and duplicates; this collapses it to the distinct pages.
  • Pulling references out of a document. Every URL cited in a report, in the order it appeared, ready to check.
  • Extracting outbound links from a page's source. Paste the HTML; href values in the markup are found the same as links in prose.
  • Making a crawl list. The domain column plus a sort gives you a per-host grouping in one step.

Once the links are a CSV, the full workbench will group them by domain, count them, and chart the result without you writing anything.

Frequently Asked Questions

Which parameters count as tracking?

An explicit list, not a pattern. The utm_ family, the advertising click ids (gclid, gbraid, wbraid, dclid, fbclid, msclkid, twclid, yclid, ttclid), the email platform ids (mc_cid, mc_eid, mkt_tok, _hsenc), the Matomo and Piwik pairs, and a few dozen more. Whatever was actually removed is named in the note above the result.

Why is a URL missing its query string?

Because every parameter on it was a tracking parameter. If a link had only ?utm_source=x on it, stripping leaves a bare path and the question mark goes too. Turn the option off to see the original.

Does it find links inside HTML attributes?

Yes. The extractor works on raw text, so a href="https://example.com" in pasted markup is found exactly the same as a link written in prose. Quote characters and angle brackets are treated as boundaries, so the URL comes out without them.

What happens to relative links like /about?

They are not extracted. A relative link has no meaning without the page it was on, and inventing a base URL would produce links to a site nobody named. Bare www. hosts are the one exception, because those are absolute in every way except the scheme.

Can I keep only the links to one site?

Turn on the domain column, download the CSV, and filter on it in a spreadsheet, or open the result in the full app and filter there in one click. The scheme filter on this page covers http, https and everything else, which is the split that usually matters for a link audit.

Are duplicates compared before or after stripping?

After, and that is the design. Comparing first would find almost nothing, since campaign variants of the same page differ by exactly the parameters being removed. Strip, then compare, then keep the first appearance of each.

Does anything I paste leave my computer?

No. There is no upload endpoint on this page and no network request in the code that does the work. JavaScript in your own tab reads the text, processes it and hands back the result. Nothing is stored between visits either, so reloading gives you an empty box again. You can confirm it by opening your browser's network panel and watching it stay quiet while you work.

Get a clean list of links

Free, no account, no upload. Paste the text, take the CSV, keep the tracking junk out of it.

Back to the extractor