Website Link Crawler & Broken Link Checker
Pricing
from $1.00 / 1,000 results
Website Link Crawler & Broken Link Checker
Crawl websites and audit internal and external links. Find broken links, redirects, HTTP status codes, anchor text, follow/nofollow links, canonical URLs, and crawl depth for SEO audits and website maintenance.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
SearchShark Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
🔗 Website Link Crawler
Website Link Crawler lets you crawl websites and extract structured SEO link data from every page.
Find broken links, analyze internal linking, detect redirects, inspect anchor text, identify follow/nofollow links, review crawl depth, and export clean source → target link relationships without manually checking pages one by one.
- 🔎 Discover website links: extract internal and external links from crawled pages
- 🚨 Find broken links: detect URLs returning HTTP errors or request failures
- ↪️ Detect redirects: capture redirect status and destination URLs
- 🧭 Analyze internal linking: preserve the exact page where every link was found
- 🏷 Inspect anchor text: extract the visible text attached to each link
- 🔗 Check follow status: distinguish normal follow links from
nofollowlinks - 📏 Track crawl depth: understand how deep each source page is from the starting URL
- 📄 Inspect page metadata: collect page titles and canonical URLs
- 🧹 Get cleaner results: normalize fragments and remove duplicate target links on the same source page
- ⚡ Automate SEO audits: export structured results to Apify Dataset, API, integrations, or downstream applications
📦 What data does Website Link Crawler extract?
| 📄 Source URL | 📝 Source page title |
| 🔖 Canonical URL | 🎯 Target URL |
| 🏷 Anchor text | 🔗 Internal / external classification |
| 👁 Follow / nofollow status | 📏 Crawl depth |
| 🌐 HTTP status code | 🚨 Broken-link status |
| ↪️ Redirect status | 🎯 Redirect destination |
| ⚠️ Request error information | 🧹 Normalized target URL |
Unavailable values are returned as
null. The Actor does not invent metadata that the website does not expose.
🚀 Features
Website Link Crawler is designed for technical SEO audits, website maintenance, site migrations, and link analysis.
- Multiple start URLs: crawl one or more websites or sections in a single Actor run
- Configurable crawl depth: control how many internal-link levels the crawler follows
- Configurable page limit: prevent unexpectedly large crawls
- Internal link discovery: capture links pointing to the same hostname
- External link discovery: capture links pointing to other hostnames
- External-link safety: external links are analyzed but are not recursively crawled
- HTTP status checking: inspect the response status of discovered targets
- Broken-link detection: mark HTTP errors and unreachable targets
- Redirect detection: identify HTTP redirects without automatically hiding the original response
- Redirect destination extraction: preserve the URL returned in the redirect
Locationheader - Follow / nofollow classification
- Anchor-text extraction
- Source page title extraction
- Canonical URL extraction
- Crawl-depth tracking
- Fragment normalization: URLs such as
/aboutand/about#teamare treated as the same HTTP resource - Per-page duplicate removal: repeated target links on the same source page are not emitted repeatedly
- Same-hostname recursive crawling
- API-friendly output: every Dataset row follows a predictable source → target relationship
- HTTP-first architecture: normal crawling does not require a browser
⬇️ Input
You can configure Website Link Crawler directly from the Apify Console or send the input programmatically through the Apify API.
🔗 Start URLs
Add one or more URLs where crawling should begin.
Example:
https://example.comhttps://example.org
Each starting URL begins at:
crawlDepth: 0
The Actor can then follow internal links depending on the configured maximum crawl depth.
📏 Max Crawl Depth
Controls how many levels of internal links the crawler follows.
Minimum: 0Default: 2Maximum: 20
Depth 0
https://example.com
Only the starting page is crawled.
Links found on that page are still analyzed and written to the Dataset, but the linked pages are not recursively crawled.
Depth 1
Example:
Start:https://example.comLinks to:https://example.com/abouthttps://example.com/services
The Actor crawls:
Depth 0 → HomepageDepth 1 → AboutDepth 1 → Services
but does not continue to depth 2.
Depth 2
Example:
Homepage↓Services↓Plumbing
becomes:
Homepage → depth 0Services → depth 1Plumbing → depth 2
The crawler stops adding deeper requests after the configured limit is reached.
🔢 Maximum Pages to Crawl
Limits how many pages the crawler may process during the Actor run.
Minimum: 1Default: 100Maximum: 100000
For example:
{"maxRequestsPerCrawl": 500}
allows the crawler to process up to 500 pages.
The requested number is a maximum, not a guarantee.
A crawl may naturally finish earlier when no new internal pages remain.
🧪 Example input
{"startUrls": [{"url": "https://example.com"}],"maxCrawlDepth": 2,"maxRequestsPerCrawl": 100}
⬆️ Output
Results are stored in the Actor's default Apify Dataset.
You can access the results from:
OutputStorageApify APIIntegrations
Each Dataset row represents:
one discovered target URL+the source page where it was found
📊 Example result
{"sourceUrl": "https://example.com/","sourceTitle": "Example Company","canonicalUrl": "https://example.com/","targetUrl": "https://example.com/services","anchorText": "Our Services","linkType": "internal","followType": "follow","crawlDepth": 0,"statusCode": 200,"isBroken": false,"isRedirect": false,"redirectUrl": null,"statusError": null}
📄 Source URL
The sourceUrl field tells you exactly where a link was discovered.
Example:
sourceUrl:https://example.com/servicestargetUrl:https://example.com/contact
This preserves the relationship:
/services → /contact
instead of returning only a flat list of URLs.
This is useful for technical SEO because you can identify which page contains the problematic link.
📝 Source page title
Each result includes:
sourceTitle
when the source page contains an HTML <title> element.
Example:
{"sourceUrl": "https://example.com/services","sourceTitle": "Home Services | Example Company"}
This makes large Dataset exports easier to understand without manually opening each source page.
🔖 Canonical URL
When the source page contains:
<link rel="canonical" href="https://example.com/preferred-page">
the Actor returns:
{"canonicalUrl": "https://example.com/preferred-page"}
Relative canonical URLs are resolved against the source page.
Example:
<link rel="canonical" href="/services">
becomes:
https://example.com/services
If no canonical tag is available:
{"canonicalUrl": null}
🔗 Internal and external links
Every target is classified as either:
internalexternal
🏠 Internal links
A link is considered internal when its hostname matches the source page hostname.
Example:
Source:https://example.com/Target:https://example.com/about
Output:
{"linkType": "internal"}
🌍 External links
Example:
Source:https://example.com/Target:https://wikipedia.org/
Output:
{"linkType": "external"}
External links are still:
extractedstatus checkedclassifiedstored
but the crawler does not recursively crawl the external website.
This prevents a normal website audit from accidentally expanding across the entire web.
🏷 Anchor text
The Actor extracts the visible text inside each link.
Example HTML:
<a href="/pricing">View our pricing</a>
Output:
{"anchorText": "View our pricing"}
This can help with:
Internal anchor-text auditsSEO optimizationNavigation analysisGeneric anchor detectionSite migration reviews
👁 Follow and nofollow links
Website Link Crawler checks the link's rel attribute.
Normal link:
<a href="/about">About</a>
Output:
{"followType": "follow"}
Nofollow link:
<a href="/partner" rel="nofollow">Partner</a>
Output:
{"followType": "nofollow"}
A link containing multiple rel values is still recognized.
Example:
<a href="/partner" rel="nofollow sponsored">
returns:
nofollow
🚨 Broken-link detection
One of the main uses of Website Link Crawler is finding links that no longer work.
The Actor checks each discovered target URL and returns:
statusCodeisBrokenstatusError
✅ Working URL
Example:
{"statusCode": 200,"isBroken": false,"statusError": null}
❌ Broken URL
Example:
{"statusCode": 404,"isBroken": true,"statusError": null}
HTTP error responses such as:
400401403404410429500503
are represented by their actual response status.
The Actor currently marks responses with status code 400 or higher as broken.
⚠️ Request failure
If the target cannot be checked because of a network/request failure:
{"statusCode": null,"isBroken": true,"statusError": "Request error information"}
This distinguishes:
HTTP error response
from:
No valid HTTP response received
↪️ Redirect detection
Redirecting links are preserved instead of automatically hiding the original response.
For example:
https://example.com/old-page
returns:
301
with:
Location: /new-page
The Actor can return:
{"targetUrl": "https://example.com/old-page","statusCode": 301,"isBroken": false,"isRedirect": true,"redirectUrl": "https://example.com/new-page"}
This is useful because SEO audits often need to identify pages that are still linking to redirected URLs.
Why redirects matter
Imagine:
Homepage↓/old-services↓ 301/new-services
The website technically works, but the internal link is outdated.
Website Link Crawler lets you identify that relationship so the original link can be updated directly to:
/new-services
📏 Crawl-depth tracking
Every result contains:
crawlDepth
The value describes the depth of the source page where the link was found.
Example:
HomepageDepth 0↓ links toServicesDepth 1↓ links toRoofingDepth 2
A link discovered on the Roofing page would therefore contain:
{"crawlDepth": 2}
This can help identify:
Deep pagesSite architecture problemsImportant content buried too far from the homepageNavigation complexityInternal-link opportunities
🧹 URL normalization and duplicate handling
Website pages often contain repeated links.
For example:
<a href="/about">About</a><a href="/about">Company</a><a href="/about#team">Our Team</a>
Website Link Crawler normalizes URL fragments before duplicate detection.
These:
https://example.com/abouthttps://example.com/about#team
are treated as the same HTTP resource for target deduplication.
The crawler keeps only the first occurrence of the normalized target URL within that source page.
This avoids:
Duplicate Dataset rowsDuplicate HTTP status requestsUnnecessary processingMessy exports
Important deduplication behavior
Deduplication is performed per source page.
This means:
Homepage → /contactServices → /contactBlog → /contact
remain three useful relationships.
That is intentional.
They represent three different internal links even though they point to the same target.
The Actor does not globally remove these relationships.
🌐 Same-hostname crawling
Recursive crawling uses a same-hostname strategy.
Example:
Start:https://example.com
The crawler may follow:
https://example.com/abouthttps://example.com/serviceshttps://example.com/blog
but it does not recursively begin crawling:
https://facebook.com/...https://youtube.com/...https://wikipedia.org/...
Those external targets can still appear in the Dataset and have their link status checked.
⚡ Performance
Website Link Crawler uses an HTTP-first architecture based on Crawlee and Cheerio.
It does not launch a browser for normal page crawling.
This generally means:
Lower memory useFaster startupLower browser overheadLower compute requirementsEfficient HTML parsing
This design is especially useful for crawling ordinary server-rendered websites.
🛡 Reliability
The Actor is designed so discovered links are processed independently.
A target status check can return:
HTTP statusredirect informationrequest error
without requiring the Dataset to hide the underlying result.
The crawler also includes:
Configurable page limitsConfigurable depth limitsPer-page URL deduplicationProtocol filteringSame-hostname recursionInvalid URL protectionRequest timeout protection
Only:
http:https:
links are analyzed as web targets.
Links using protocols such as:
mailto:tel:javascript:
are currently skipped.
🔌 API & integrations
Website Link Crawler can be used programmatically through the Apify API.
You can connect Dataset results to workflows such as:
- Google Sheets
- Make
- Zapier
- CRMs
- Internal APIs
- Data warehouses
- SEO reporting systems
- Website monitoring workflows
- AI agents
- MCP workflows
Each Actor run stores structured source → target link relationships in the default Dataset, making the output straightforward to process with another application.
💡 Example use cases
🚨 Broken-link audit
Run the crawler on your website and filter:
isBroken = true
to identify URLs that may need attention.
Useful output:
Source pageBroken targetAnchor textHTTP statusCrawl depth
This tells you both what is broken and where the broken link exists.
↪️ Redirect cleanup
Filter:
isRedirect = true
to locate links pointing to redirects.
Example:
Source:https://example.com/Target:https://example.com/old-pricingRedirect:https://example.com/pricing
You can then update the source page to point directly to the final URL.
🧭 Internal-link audit
Filter:
linkType = internal
to analyze relationships between pages on the website.
Use:
sourceUrltargetUrlanchorTextcrawlDepth
to understand the internal linking structure.
🌍 External-link audit
Filter:
linkType = external
to review websites being linked to from your pages.
This can help identify:
Dead external referencesRedirecting external linksOld resourcesUnexpected outbound links
🏷 Anchor-text analysis
Export:
sourceUrltargetUrlanchorText
to inspect how internal links are labeled.
Example:
/services → /contact → Contact us/blog/article → /contact → Get a quote/pricing → /contact → Start today
This can support internal-link and SEO reviews.
📏 Site-depth analysis
Use:
crawlDepth
to find pages and links located deeper within the site's architecture.
For example:
Depth 0 → HomepageDepth 1 → Main categoryDepth 2 → SubcategoryDepth 3 → Individual page
Deep pages may be useful candidates for additional internal links.
🚚 Website migration auditing
Before or after a website migration, crawl the site and inspect:
404 links301 redirectsOld internal URLsCanonical URLsInternal anchor textSource → target relationships
This helps identify links that still point to outdated paths.
⚠️ Current limitations
The current version focuses on fast HTTP-based website link analysis.
It does not currently perform:
JavaScript/browser-rendered link discoveryRedirect-chain traversalInternal-link graph visualizationSite-wide orphan-page detectionXML sitemap comparisonrobots.txt auditingHreflang auditingMeta robots analysisStructured-data auditingPage-speed analysisFull page-content extractionDomain-level link summariesSite-wide anchor-text summariesAutomatic scheduled historical comparisons
These are intentionally separate from the current MVP.
JavaScript-rendered websites
The Actor currently uses:
HTTP+Cheerio
instead of Playwright or Puppeteer.
If a website creates links only after JavaScript executes in the browser, those links may not appear in the HTML received by the crawler.
For ordinary server-rendered HTML websites, this is not a problem.
Browser-rendered crawling can be introduced later as a separate mode if needed.
❓ FAQ
How does Website Link Crawler work?
The Actor starts from the URLs you provide.
It then:
Downloads the source pageParses HTMLFinds <a href> linksNormalizes target URLsRemoves duplicate targets on that pageExtracts anchor textClassifies internal/externalDetects follow/nofollowChecks HTTP statusDetects redirectsStores source → target relationshipsFollows eligible internal linksTracks crawl depthStops at configured limits
What is the difference between this and a normal URL crawler?
A normal crawler may return:
https://example.comhttps://example.com/abouthttps://example.com/services
Website Link Crawler returns relationships such as:
Homepage↓ "Our services"/servicesHTTP 200InternalFollowDepth 0
This makes the output more useful for SEO audits and website maintenance.
Does the Actor find backlinks?
No.
This Actor discovers links on the website being crawled.
Example:
example.com/page-a↓example.com/page-b
A backlink tool would instead need to discover:
otherwebsite.com↓example.com
Those are different problems.
Website Link Crawler is an on-site link crawler, not a global backlink index.
Does it crawl external websites?
No.
External links are:
discoveredclassifiedstatus checkedstored
but they are not recursively crawled.
This prevents an audit from expanding uncontrollably across unrelated websites.
Does it detect broken links?
Yes.
The Actor marks:
HTTP status >= 400
as broken.
It also marks targets as broken when the status request cannot be completed.
Does a redirect count as a broken link?
No.
For example:
301302307308
are treated as redirects rather than broken HTTP errors.
A redirecting URL can therefore return:
{"isBroken": false,"isRedirect": true}
Does it follow redirects?
The current status checker preserves the original redirect response.
It returns:
Original status codeRedirect indicatorRedirect destination
Example:
301https://example.com/new-page
It does not currently build a full multi-hop redirect chain.
Does it remove duplicate links?
Yes, within each source page.
For example:
/about/about/about#team
are normalized and treated as one target resource on that source page.
But:
Homepage → /aboutServices → /aboutBlog → /about
are all retained because each represents a different source → target relationship.
Does it extract canonical URLs?
Yes, when present in the source HTML.
Example:
<link rel="canonical" href="/preferred-page">
is resolved to an absolute URL.
If no canonical exists:
canonicalUrl: null
Can I control how deeply the website is crawled?
Yes.
Use:
maxCrawlDepth
Current limits:
Minimum: 0Default: 2Maximum: 20
Can I limit how many pages are crawled?
Yes.
Use:
maxRequestsPerCrawl
Current limits:
Minimum: 1Default: 100Maximum: 100000
Can I crawl multiple websites in one run?
Yes.
You can provide multiple:
startUrls
in the same Actor input.
Each start request begins at crawl depth 0.
Can I use Website Link Crawler through an API?
Yes.
Every Actor can be started through the Apify API, and the resulting Dataset can be consumed programmatically.
This makes Website Link Crawler suitable for:
Automated SEO auditsWebsite QA pipelinesMigration checksReporting systemsInternal toolsScheduled workflows
Can I export the results?
Yes.
Apify Dataset results can be exported in supported formats such as:
JSONCSVExcelXMLHTML
Is a browser required?
Not for the current workflow.
Website Link Crawler uses an HTTP-first approach with:
CrawleeCheerio
which avoids launching full browser automation during normal crawls.
Why is canonicalUrl sometimes null?
Because not every page contains a canonical tag.
The Actor returns:
null
instead of inventing one.
Why is statusCode sometimes null?
This means the status request did not receive a normal HTTP response.
The associated:
statusError
field may contain additional information about the request failure.
🧭 Recommended workflow
For a normal SEO website audit, start conservatively.
Example:
{"startUrls": [{"url": "https://example.com"}],"maxCrawlDepth": 2,"maxRequestsPerCrawl": 500}
First inspect:
isBrokenisRedirectlinkTypecrawlDepthcanonicalUrlanchorText
Then increase the crawl depth or maximum pages if additional coverage is needed.
For very large websites, avoid immediately using extremely high limits before understanding the site's linking structure.
💬 Feedback & support
Found a bug or have a feature request?
Use the Actor's Issues tab on Apify.
Useful future additions may include:
Redirect-chain detectionInternal-link graphPages with very few internal linksPages with excessive outgoing linksExternal-domain summariesSite-wide anchor-text summariesSitemap comparisonJavaScript rendering modeOrphan-page analysisHistorical website audit comparisons
🚀 Website link auditing without manually checking every page
Enter your website URL, choose the crawl depth, run the Actor, and receive structured source → target link data ready for SEO audits, broken-link cleanup, migration analysis, APIs, and automation.