2026-02-05 04:11:15 +00:00
<! DOCTYPE html >
< html lang = " en " >
< head >
< meta charset = " UTF-8 " >
< meta name = " viewport " content = " width=device-width, initial-scale=1.0 " >
< title > Web Scraping Cost Calculator | UK Data Services </ title >
< meta name = " description " content = " Estimate your web scraping project cost instantly. Our free calculator helps UK businesses budget for data extraction, pricing intelligence, and market research projects. " >
< meta name = " keywords " content = " web scraping cost, data extraction pricing, scraping quote, web scraping calculator UK " >
Fix navbar across all pages: add nav include, fonts, active state, spacing, stats, error pages
- Add nav.php include to 5 missing pages (cost-calculator, thank-you, 403, 404, 500)
- Add ErrorDocument directives to .htaccess for custom 403/404/500 pages
- Fix bogus accuracy stats (homepage, web-scraping, location pages)
- Fix invisible CTA buttons on property and financial service pages
- Add Google Fonts (Roboto Slab + Lato) to all pages missing it (tools, blog articles, error pages)
- Add active nav link highlighting (teal underline for current page)
- Improve footer contrast to WCAG AA, equal-height cards, mobile text scaling
- Consistent navbar-to-content spacing across all pages
- Bump cache version to v1.1.3
2026-02-11 07:15:11 +00:00
< link rel = " preconnect " href = " https://fonts.googleapis.com " >
< link rel = " preconnect " href = " https://fonts.gstatic.com " crossorigin >
< link href = " https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@100;200;300;400;500;600;700;800;900&family=Lato:wght@100;200;300;400;500;600;700;800;900&display=swap " rel = " stylesheet " >
< link rel = " canonical " href = " https://ukdataservices.co.uk/tools/cost-calculator " >
2026-02-05 04:11:15 +00:00
<!-- Open Graph -->
< meta property = " og:title " content = " Free Web Scraping Cost Calculator " >
< meta property = " og:description " content = " Get an instant estimate for your web scraping project. Used by 500+ UK businesses. " >
< meta property = " og:type " content = " website " >
< meta property = " og:url " content = " https://ukdataservices.co.uk/tools/cost-calculator " >
< link rel = " stylesheet " href = " ../assets/css/main.css " >
< style >
. calculator - container {
max - width : 800 px ;
margin : 0 auto ;
padding : 40 px 20 px ;
}
. calculator - header {
text - align : center ;
margin - bottom : 40 px ;
}
. calculator - header h1 {
font - size : 2.2 em ;
color : #1a1a2e;
margin - bottom : 15 px ;
}
. calculator - header p {
color : #666;
font - size : 1.1 em ;
max - width : 600 px ;
margin : 0 auto ;
}
. calculator - card {
background : #fff;
border - radius : 12 px ;
box - shadow : 0 4 px 20 px rgba ( 0 , 0 , 0 , 0.08 );
padding : 40 px ;
}
. form - group {
margin - bottom : 30 px ;
}
. form - group label {
display : block ;
font - weight : 600 ;
color : #1a1a2e;
margin - bottom : 10 px ;
font - size : 1 em ;
}
. form - group . hint {
font - weight : 400 ;
color : #888;
font - size : 0.85 em ;
display : block ;
margin - top : 4 px ;
}
. option - grid {
display : grid ;
grid - template - columns : repeat ( auto - fit , minmax ( 150 px , 1 fr ));
gap : 12 px ;
}
. option - card {
border : 2 px solid #e0e0e0;
border - radius : 8 px ;
padding : 15 px ;
text - align : center ;
cursor : pointer ;
transition : all 0.2 s ;
}
. option - card : hover {
border - color : #0066cc;
background : #f8fbff;
}
. option - card . selected {
border - color : #0066cc;
background : #e8f4fd;
}
. option - card . icon {
font - size : 1.8 em ;
margin - bottom : 8 px ;
}
. option - card . label {
font - weight : 600 ;
color : #333;
}
. option - card . desc {
font - size : 0.8 em ;
color : #888;
margin - top : 4 px ;
}
input [ type = " number " ], select {
width : 100 % ;
padding : 14 px ;
border : 2 px solid #e0e0e0;
border - radius : 8 px ;
font - size : 1 em ;
transition : border - color 0.2 s ;
}
input [ type = " number " ] : focus , select : focus {
border - color : #0066cc;
outline : none ;
}
. slider - container {
margin - top : 10 px ;
}
input [ type = " range " ] {
width : 100 % ;
margin : 10 px 0 ;
}
. slider - labels {
display : flex ;
justify - content : space - between ;
font - size : 0.85 em ;
color : #888;
}
. result - section {
background : linear - gradient ( 135 deg , #1a1a2e 0%, #16213e 100%);
border - radius : 12 px ;
padding : 30 px ;
margin - top : 30 px ;
color : #fff;
text - align : center ;
}
. result - section h3 {
margin : 0 0 10 px 0 ;
font - size : 1 em ;
font - weight : 400 ;
opacity : 0.8 ;
}
. estimate - range {
font - size : 2.5 em ;
font - weight : 700 ;
margin : 10 px 0 ;
}
. estimate - note {
font - size : 0.9 em ;
opacity : 0.7 ;
margin - bottom : 25 px ;
}
. result - cta {
display : flex ;
gap : 15 px ;
justify - content : center ;
flex - wrap : wrap ;
}
. btn - primary {
background : #00cc66;
color : #fff;
padding : 14 px 28 px ;
border : none ;
border - radius : 8 px ;
font - size : 1 em ;
font - weight : 600 ;
cursor : pointer ;
text - decoration : none ;
display : inline - block ;
}
. btn - primary : hover {
background : #00b359;
}
. btn - secondary {
background : transparent ;
color : #fff;
padding : 14 px 28 px ;
border : 2 px solid rgba ( 255 , 255 , 255 , 0.3 );
border - radius : 8 px ;
font - size : 1 em ;
cursor : pointer ;
text - decoration : none ;
}
. btn - secondary : hover {
border - color : #fff;
}
. trust - signals {
display : flex ;
justify - content : center ;
gap : 30 px ;
margin - top : 30 px ;
flex - wrap : wrap ;
}
. trust - item {
text - align : center ;
color : #666;
font - size : 0.9 em ;
}
. trust - item . number {
font - size : 1.5 em ;
font - weight : 700 ;
color : #0066cc;
display : block ;
}
. email - capture {
display : none ;
background : #f8f9fa;
border - radius : 8 px ;
padding : 25 px ;
margin - top : 20 px ;
}
. email - capture . show {
display : block ;
}
. email - capture h4 {
margin : 0 0 15 px 0 ;
}
. email - capture input [ type = " email " ] {
width : 100 % ;
padding : 12 px ;
border : 2 px solid #e0e0e0;
border - radius : 6 px ;
margin - bottom : 10 px ;
box - sizing : border - box ;
}
@ media ( max - width : 600 px ) {
. calculator - card { padding : 25 px ; }
. estimate - range { font - size : 1.8 em ; }
. result - cta { flex - direction : column ; }
}
</ style >
</ head >
< body >
Fix navbar across all pages: add nav include, fonts, active state, spacing, stats, error pages
- Add nav.php include to 5 missing pages (cost-calculator, thank-you, 403, 404, 500)
- Add ErrorDocument directives to .htaccess for custom 403/404/500 pages
- Fix bogus accuracy stats (homepage, web-scraping, location pages)
- Fix invisible CTA buttons on property and financial service pages
- Add Google Fonts (Roboto Slab + Lato) to all pages missing it (tools, blog articles, error pages)
- Add active nav link highlighting (teal underline for current page)
- Improve footer contrast to WCAG AA, equal-height cards, mobile text scaling
- Consistent navbar-to-content spacing across all pages
- Bump cache version to v1.1.3
2026-02-11 07:15:11 +00:00
< ? php include ( $_SERVER [ " DOCUMENT_ROOT " ] . " /includes/nav.php " ); ?>
2026-02-05 04:11:15 +00:00
<!-- Header would be included here -->
< div class = " calculator-container " >
< div class = " calculator-header " >
< h1 > 🧮 Web Scraping Cost Calculator </ h1 >
< p > Get an instant estimate for your data extraction project . Answer a few questions and we ' ll show you typical pricing .</ p >
</ div >
< div class = " calculator-card " >
< form id = " calculator-form " >
<!-- Project Type -->
< div class = " form-group " >
< label > What type of data do you need ? </ label >
< div class = " option-grid " data - field = " projectType " >
< div class = " option-card " data - value = " pricing " >
< div class = " icon " > 💰 </ div >
< div class = " label " > Competitor Pricing </ div >
< div class = " desc " > Product prices & stock </ div >
</ div >
< div class = " option-card " data - value = " leads " >
< div class = " icon " > 👥 </ div >
< div class = " label " > Lead Generation </ div >
< div class = " desc " > Business contacts </ div >
</ div >
< div class = " option-card " data - value = " market " >
< div class = " icon " > 📊 </ div >
< div class = " label " > Market Research </ div >
< div class = " desc " > Reviews , trends , content </ div >
</ div >
< div class = " option-card " data - value = " property " >
< div class = " icon " > 🏠 </ div >
< div class = " label " > Property Data </ div >
< div class = " desc " > Listings & valuations </ div >
</ div >
< div class = " option-card " data - value = " custom " >
< div class = " icon " > ⚙️ </ div >
< div class = " label " > Custom Project </ div >
< div class = " desc " > Something else </ div >
</ div >
</ div >
</ div >
<!-- Number of Sources -->
< div class = " form-group " >
< label >
How many websites do you need to scrape ?
< span class = " hint " > Each unique website counts as one source </ span >
</ label >
< div class = " slider-container " >
< input type = " range " id = " numSources " min = " 1 " max = " 50 " value = " 5 " oninput = " updateSourcesLabel(this.value); calculate(); " >
< div class = " slider-labels " >
< span > 1 site </ span >
< span id = " sources-value " > 5 sites </ span >
< span > 50 + sites </ span >
</ div >
</ div >
</ div >
<!-- Data Volume -->
< div class = " form-group " >
< label >
How many records / items do you need ?
< span class = " hint " > Products , listings , contacts , etc .</ span >
</ label >
< div class = " option-grid " data - field = " volume " >
< div class = " option-card " data - value = " small " >
< div class = " label " >< 1 , 000 </ div >
< div class = " desc " > Small dataset </ div >
</ div >
< div class = " option-card " data - value = " medium " >
< div class = " label " > 1 K - 10 K </ div >
< div class = " desc " > Medium dataset </ div >
</ div >
< div class = " option-card " data - value = " large " >
< div class = " label " > 10 K - 100 K </ div >
< div class = " desc " > Large dataset </ div >
</ div >
< div class = " option-card " data - value = " enterprise " >
< div class = " label " > 100 K +</ div >
< div class = " desc " > Enterprise scale </ div >
</ div >
</ div >
</ div >
<!-- Frequency -->
< div class = " form-group " >
< label >
How often do you need the data updated ?
< span class = " hint " > Recurring scrapes have ongoing monthly costs </ span >
</ label >
< div class = " option-grid " data - field = " frequency " >
< div class = " option-card " data - value = " once " >
< div class = " label " > One - time </ div >
< div class = " desc " > Single extraction </ div >
</ div >
< div class = " option-card " data - value = " weekly " >
< div class = " label " > Weekly </ div >
< div class = " desc " > Updated each week </ div >
</ div >
< div class = " option-card " data - value = " daily " >
< div class = " label " > Daily </ div >
< div class = " desc " > Fresh data daily </ div >
</ div >
< div class = " option-card " data - value = " realtime " >
< div class = " label " > Real - time </ div >
< div class = " desc " > Continuous monitoring </ div >
</ div >
</ div >
</ div >
<!-- Complexity -->
< div class = " form-group " >
< label >
How complex are the target websites ?
< span class = " hint " > JavaScript - heavy sites and those with anti - bot measures cost more </ span >
</ label >
< div class = " option-grid " data - field = " complexity " >
< div class = " option-card " data - value = " simple " >
< div class = " label " > Simple </ div >
< div class = " desc " > Static HTML pages </ div >
</ div >
< div class = " option-card " data - value = " moderate " >
< div class = " label " > Moderate </ div >
< div class = " desc " > Some JavaScript </ div >
</ div >
< div class = " option-card " data - value = " complex " >
< div class = " label " > Complex </ div >
< div class = " desc " > Heavy JS , logins </ div >
</ div >
< div class = " option-card " data - value = " extreme " >
< div class = " label " > Very Complex </ div >
< div class = " desc " > Anti - bot , CAPTCHAs </ div >
</ div >
</ div >
</ div >
</ form >
<!-- Results -->
< div class = " result-section " id = " results " style = " display:none; " >
< h3 > Estimated Project Cost </ h3 >
< div class = " estimate-range " id = " estimate-range " > £500 - £1 , 500 </ div >
< div class = " estimate-note " id = " estimate-note " > One - time setup cost </ div >
< div class = " estimate-note " id = " monthly-note " style = " display:none; " >+ < span id = " monthly-cost " > £200 </ span >/ month ongoing </ div >
< div class = " result-cta " >
< a href = " /quote " class = " btn-primary " onclick = " trackCalculator('get_quote') " > Get Exact Quote </ a >
< button type = " button " class = " btn-secondary " onclick = " showEmailCapture() " > Email Me This Estimate </ button >
</ div >
</ div >
<!-- Email Capture -->
< div class = " email-capture " id = " email-capture " >
< h4 > 📧 Get your estimate + our pricing guide </ h4 >
< input type = " email " id = " calc-email " placeholder = " Enter your email " >
< button type = " button " class = " btn-primary " onclick = " submitEmail() " style = " width:100%; " > Send My Estimate </ button >
</ div >
</ div >
< div class = " trust-signals " >
< div class = " trust-item " >
< span class = " number " > 500 +</ span >
Projects Delivered
</ div >
< div class = " trust-item " >
< span class = " number " > 99.8 %</ span >
Data Accuracy
</ div >
< div class = " trust-item " >
< span class = " number " > 24 hr </ span >
Quote Turnaround
</ div >
</ div >
</ div >
< script >
var formData = {
projectType : null ,
numSources : 5 ,
volume : null ,
frequency : null ,
complexity : null
};
// Option card selection
document . querySelectorAll ( '.option-grid' ) . forEach ( function ( grid ) {
grid . querySelectorAll ( '.option-card' ) . forEach ( function ( card ) {
card . addEventListener ( 'click' , function () {
var field = this . parentElement . dataset . field ;
this . parentElement . querySelectorAll ( '.option-card' ) . forEach ( function ( c ) {
c . classList . remove ( 'selected' );
});
this . classList . add ( 'selected' );
formData [ field ] = this . dataset . value ;
calculate ();
});
});
});
function updateSourcesLabel ( value ) {
document . getElementById ( 'sources-value' ) . textContent = value + ( value == 1 ? ' site' : ' sites' );
formData . numSources = parseInt ( value );
}
function calculate () {
if ( ! formData . projectType || ! formData . volume || ! formData . frequency || ! formData . complexity ) {
return ;
}
// Base costs by project type
var baseCosts = {
pricing : 600 ,
leads : 400 ,
market : 500 ,
property : 700 ,
custom : 800
};
// Volume multipliers
var volumeMultipliers = {
small : 1 ,
medium : 1.5 ,
large : 2.5 ,
enterprise : 4
};
// Complexity multipliers
var complexityMultipliers = {
simple : 1 ,
moderate : 1.5 ,
complex : 2.5 ,
extreme : 4
};
// Calculate base
var base = baseCosts [ formData . projectType ];
base *= volumeMultipliers [ formData . volume ];
base *= complexityMultipliers [ formData . complexity ];
base *= ( 1 + ( formData . numSources - 1 ) * 0.3 ); // Each additional source adds 30%
// Round to nice numbers
var low = Math . round ( base / 100 ) * 100 ;
var high = Math . round (( base * 1.8 ) / 100 ) * 100 ;
// Monthly costs for recurring
var monthlyLow = 0 ;
var monthlyHigh = 0 ;
if ( formData . frequency !== 'once' ) {
var freqMultipliers = { weekly : 0.15 , daily : 0.25 , realtime : 0.5 };
monthlyLow = Math . round (( low * freqMultipliers [ formData . frequency ]) / 50 ) * 50 ;
monthlyHigh = Math . round (( high * freqMultipliers [ formData . frequency ]) / 50 ) * 50 ;
}
// Display results
document . getElementById ( 'results' ) . style . display = 'block' ;
document . getElementById ( 'estimate-range' ) . textContent = '£' + low . toLocaleString () + ' - £' + high . toLocaleString ();
if ( formData . frequency === 'once' ) {
document . getElementById ( 'estimate-note' ) . textContent = 'One-time project cost' ;
document . getElementById ( 'monthly-note' ) . style . display = 'none' ;
} else {
document . getElementById ( 'estimate-note' ) . textContent = 'Initial setup cost' ;
document . getElementById ( 'monthly-note' ) . style . display = 'block' ;
document . getElementById ( 'monthly-cost' ) . textContent = '£' + monthlyLow + ' - £' + monthlyHigh ;
}
// Track calculation
if ( typeof gtag !== 'undefined' ) {
gtag ( 'event' , 'calculator_result' , {
event_category : 'Calculator' ,
event_label : formData . projectType ,
value : low
});
}
}
function showEmailCapture () {
document . getElementById ( 'email-capture' ) . classList . add ( 'show' );
trackCalculator ( 'show_email_capture' );
}
function submitEmail () {
var email = document . getElementById ( 'calc-email' ) . value ;
if ( ! email || ! email . includes ( '@' )) {
alert ( 'Please enter a valid email' );
return ;
}
var estimate = document . getElementById ( 'estimate-range' ) . textContent ;
fetch ( '/api/lead-capture.php' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON . stringify ({
email : email ,
source : 'calculator' ,
estimate : estimate ,
formData : formData ,
page : window . location . pathname
})
});
document . getElementById ( 'email-capture' ) . innerHTML = '<h4>✅ Sent! Check your inbox.</h4><p>We have also sent our detailed pricing guide.</p>' ;
trackCalculator ( 'email_submitted' );
}
function trackCalculator ( action ) {
if ( typeof gtag !== 'undefined' ) {
gtag ( 'event' , action , { event_category : 'Calculator' });
}
console . log ( 'Calculator:' , action );
}
</ script >
</ body >
</ html >
<!-- SoftwareApplication Schema - Added by Emma -->
< script type = " application/ld+json " >
{
" @context " : " https://schema.org " ,
" @type " : " SoftwareApplication " ,
" name " : " Web Scraping Cost Calculator " ,
" description " : " Free tool to estimate web scraping project costs for UK businesses " ,
" url " : " https://ukdataservices.co.uk/tools/cost-calculator " ,
" applicationCategory " : " BusinessApplication " ,
" operatingSystem " : " Web Browser " ,
" offers " : {
" @type " : " Offer " ,
" price " : " 0 " ,
" priceCurrency " : " GBP "
},
" provider " : {
" @type " : " Organization " ,
" name " : " UK Data Services " ,
" url " : " https://ukdataservices.co.uk "
}
}
</ script >