Crawling

What Is Link Extraction in Web Crawling?

By the Scrappey Research Team

What Is Link Extraction in Web Crawling? — conceptual illustration
On this page

Link extraction is the crawling step where you pull every URL out of a page you have just downloaded, so you can decide which ones to visit next. The result is a clean list of full (absolute) URLs with duplicates removed. It sounds trivial, but the awkward cases - relative URLs (shorthand paths like /about that omit the domain), anchors that only jump within the page, links that exist only after JavaScript runs, data-href attributes, and links buried in event handlers - make it the number-one cause of "missing pages" bugs in crawlers.

Quick facts

Source<a href> primarily; also <link>, <area>, <iframe src>
StepsParse → resolve relative URLs → strip fragments → normalize → dedupe
Easy to missJS-rendered links, data-* attributes, onclick handlers
NormalizeLowercase host, sort query params, strip trailing slashes consistently
OutputSet of absolute, normalized URLs for the frontier

The basic algorithm

Parse the HTML (turn the raw text into a structure you can search). Select every <a> tag that has an href attribute. Resolve each href against the page's base URL - that is, combine a relative path like /about with the page's address to get a full URL (and respect the <base> tag if the page has one). Strip the fragment (the #section part, which only scrolls within a page). Drop javascript:, mailto:, tel:, and empty hrefs, since none of those are pages to crawl. Normalize so equivalent URLs look identical: lowercase the host, decode percent-encoding (turn %20 back into a space), and sort query parameters alphabetically. Finally, dedupe against the seen-set - the running list of URLs you have already collected.

Edge cases that cause missing pages

Links in data-href, data-url, or other custom attributes — most parsers ignore them because they only look at standard href. Links inside JSON-LD structured data (machine-readable metadata embedded in the page) — same problem. Links built dynamically from React state — only visible after the page renders. PDF/document URLs in <embed> and <object> tags — easy to skip. For a thorough crawl, audit one rendered page by hand and compare against your extractor's output to see what it is dropping.

Code example

python
from urllib.parse import urljoin, urldefrag, urlparse, parse_qsl, urlencode
from bs4 import BeautifulSoup

def extract_links(html, base_url):
    soup = BeautifulSoup(html, 'html.parser')
    base = soup.find('base', href=True)
    base_url = urljoin(base_url, base['href']) if base else base_url
    links = set()
    for a in soup.select('a[href]'):
        href = a['href'].strip()
        if not href or href.startswith(('javascript:', 'mailto:', 'tel:')):
            continue
        clean = urldefrag(urljoin(base_url, href)).url
        p = urlparse(clean)
        sorted_q = urlencode(sorted(parse_qsl(p.query)))
        links.add(p._replace(query=sorted_q).geturl())
    return links

Related terms

Concept map

How Link Extraction connects

The terms most directly tied to this one. Hover a node to see its neighbours, click to preview, drag to rearrange.

0 terms · 0 connections
You are here · Crawling
Building map…

Tools & solutions for this topic

Frequently asked questions

Should I normalize trailing slashes?

Yes, but pick one rule and apply it consistently. A path with a trailing slash and the same path without one usually point to the exact same page; if you treat them as two different URLs, you crawl that page twice and waste crawl budget for nothing.

Do I extract links from PDFs?

Only if your scope requires it. Pulling links out of PDFs is a separate problem with its own tools (pdfplumber or similar), and most crawls never need it.

What about links in noindex pages?

A noindex page is one that asks search engines not to list it in results. For SEO crawls, still follow its links but tag them as "from-noindex", because search engines do not give those links ranking credit. For data crawls, just follow them like any other link.

Last updated: 2026-05-31