SEO: all remaining items — bak cleanup, sitemap, homepage, FAQ schema, inline links

- Delete all .bak files from web root (security fix)
- Regenerate sitemap-blog.xml with all 41 articles and correct lastmod dates
- Improve homepage meta description (more specific, no contract mention)
- Add FAQPage schema to Python pipeline article (4 Q&As)
- Fix London analytics article: author, meta description updated
- Add contextual inline links to 4 articles -> service pages
- Remove includes.bak.20260210 directory
This commit is contained in:
root
2026-02-22 10:02:32 +00:00
committed by Peter Foster
parent 6f8a0490fc
commit 27f071604d
41 changed files with 257 additions and 14698 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,10 @@ header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
// SEO and performance optimizations // SEO and performance optimizations
$page_title = "10 Best Data Analytics Companies in London — 2026 Rankings & Reviews"; $page_title = "10 Best Data Analytics Companies in London — 2026 Rankings & Reviews";
$page_description = "Compare London's top 10 analytics firms by pricing, speciality & verified reviews. Find your ideal data partner in minutes."; $page_description = "Independent ranking of London's top 10 data analytics companies in 2026. Compare pricing, specialisms, client reviews & response times. Updated February 2026.";
$canonical_url = "https://ukdataservices.co.uk/blog/articles/data-analytics-companies-london-top-providers-compared"; $canonical_url = "https://ukdataservices.co.uk/blog/articles/data-analytics-companies-london-top-providers-compared";
$keywords = "data analytics companies London, business intelligence firms London, data science companies UK, analytics consultants London, big data companies"; $keywords = "data analytics companies London, business intelligence firms London, data science companies UK, analytics consultants London, big data companies";
$author = "UK Data Services Editorial Team"; $article_author = "Emma Richardson";
$og_image = "https://ukdataservices.co.uk/assets/images/blog/data-analytics-companies-london.png"; $og_image = "https://ukdataservices.co.uk/assets/images/blog/data-analytics-companies-london.png";
$published_date = "2025-08-08"; $published_date = "2025-08-08";
$modified_date = "2025-08-08"; $modified_date = "2025-08-08";
@@ -625,7 +625,7 @@ $modified_date = "2025-08-08";
<h4>Key Analytics Applications</h4> <h4>Key Analytics Applications</h4>
<ul> <ul>
<li>Customer segmentation and personalization</li> <li>Customer segmentation and personalization</li>
<li>Price optimization and competitive intelligence</li> <li>Price optimization and <a href="/services/competitive-intelligence.php" title="competitive intelligence services UK">competitive intelligence</a></li>
<li>Inventory management and demand forecasting</li> <li>Inventory management and demand forecasting</li>
<li>Marketing attribution and ROI analysis</li> <li>Marketing attribution and ROI analysis</li>
<li>Supply chain optimization</li> <li>Supply chain optimization</li>

View File

@@ -373,7 +373,7 @@ $read_time = 9;
<h4><a href="data-automation-strategies-uk-businesses.php">Data Automation Strategies for UK Businesses</a></h4> <h4><a href="data-automation-strategies-uk-businesses.php">Data Automation Strategies for UK Businesses</a></h4>
<span class="read-time">9 min read</span> <article class="related-card"> <span class="read-time">9 min read</span> <article class="related-card">
<span class="category">Business Intelligence</span> <span class="category">Business Intelligence</span>
<h4><a href="competitive-intelligence-roi-metrics.php">Measuring ROI from Competitive Intelligence Programmes</a></h4> <h4><a href="competitive-intelligence-roi-metrics.php">Measuring ROI from <a href="/services/competitive-intelligence.php" title="competitive intelligence services UK">Competitive Intelligence</a> Programmes</a></h4>
<span class="read-time">8 min read</span> <article class="related-card"> <span class="read-time">8 min read</span> <article class="related-card">
<span class="category">Compliance</span> <span class="category">Compliance</span>
<h4><a href="web-scraping-compliance-uk-guide.php">Complete Guide to Web Scraping Compliance in the UK</a></h4> <h4><a href="web-scraping-compliance-uk-guide.php">Complete Guide to Web Scraping Compliance in the UK</a></h4>

View File

@@ -124,7 +124,7 @@ $breadcrumbs = [
<div class="inline-cta"> <div class="inline-cta">
<h4>📈 Want Real-Time E-commerce Intelligence?</h4> <h4>📈 Want Real-Time E-commerce Intelligence?</h4>
<p>We track competitor prices, stock levels, and market trends across thousands of UK e-commerce sites. Get the data your rivals are using.</p> <p>We track <a href="/services/price-monitoring.php" title="competitor price monitoring UK">competitor price</a>s, stock levels, and market trends across thousands of UK e-commerce sites. Get the data your rivals are using.</p>
<a href="/quote" class="cta-link">See What We Can Track For You →</a> <a href="/quote" class="cta-link">See What We Can Track For You →</a>
</div> </div>

View File

@@ -1,391 +0,0 @@
<?php
// Security headers
header('Content-Security-Policy: default-src \'self\'; script-src \'self\' \'unsafe-inline\' https://www.googletagmanager.com; style-src \'self\' \'unsafe-inline\' https://fonts.googleapis.com; font-src \'self\' https://fonts.gstatic.com; img-src \'self\' data: https:; connect-src \'self\' https://www.google-analytics.com https://analytics.google.com https://region1.google-analytics.com;');
// Article-specific variables
$article_title = 'Python Data Pipeline Tools 2026: Airflow vs Prefect vs Dagster Compared';
$article_description = 'Compare Airflow, Prefect & Dagster head-to-head. Benchmarks, pricing & code examples for Python data pipelines in 2026.';
$article_keywords = 'Python data pipelines, Apache Airflow, Prefect, Dagster, data engineering, ETL, data orchestration, workflow automation, Python tools';
$article_author = 'Alex Kumar';
$article_date = '2024-06-04';
$last_modified = '2024-06-04';
$article_slug = 'python-data-pipeline-tools-2025';
$article_category = 'Technology';
$hero_image = '/assets/images/hero-data-analytics.svg';
// Breadcrumb navigation
$breadcrumbs = [
['url' => '/', 'label' => 'Home'],
['url' => '/blog', 'label' => 'Blog'],
['url' => '/blog/categories/technology.php', 'label' => 'Technology'],
['url' => '', 'label' => 'Python Data Pipeline Tools 2025']
];
?>
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title><?php echo htmlspecialchars($article_title); ?> | UK Data Services Blog</title>
<meta name="description" content="<?php echo htmlspecialchars($article_description); ?>">
<meta name="keywords" content="<?php echo htmlspecialchars($article_keywords); ?>">
<meta name="author" content="<?php echo htmlspecialchars($article_author); ?>">
<meta property="og:title" content="<?php echo htmlspecialchars($article_title); ?>">
<meta property="og:description" content="<?php echo htmlspecialchars($article_description); ?>">
<meta property="og:type" content="article">
<meta property="og:url" content="https://ukdataservices.co.uk/blog/articles/<?php echo $article_slug; ?>">
<meta property="og:image" content="https://ukdataservices.co.uk<?php echo $hero_image; ?>">
<meta property="article:author" content="<?php echo htmlspecialchars($article_author); ?>">
<meta property="article:published_time" content="<?php echo $article_date; ?>T09:00:00+00:00">
<meta property="article:modified_time" content="<?php echo $last_modified; ?>T09:00:00+00:00">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<?php echo htmlspecialchars($article_title); ?>">
<meta name="twitter:description" content="<?php echo htmlspecialchars($article_description); ?>">
<meta name="twitter:image" content="https://ukdataservices.co.uk<?php echo $hero_image; ?>">
<link rel="canonical" href="https://ukdataservices.co.uk/blog/articles/<?php echo $article_slug; ?>">
<link rel="stylesheet" href="/assets/css/main.css">
<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=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<?php include($_SERVER['DOCUMENT_ROOT'] . '/add_inline_css.php'); ?>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "<?php echo htmlspecialchars($article_title); ?>",
"description": "<?php echo htmlspecialchars($article_description); ?>",
"image": "https://ukdataservices.co.uk<?php echo $hero_image; ?>",
"datePublished": "<?php echo $article_date; ?>T09:00:00+00:00",
"dateModified": "<?php echo $last_modified; ?>T09:00:00+00:00",
"author": {
"@type": "Person",
"name": "<?php echo htmlspecialchars($article_author); ?>"
},
"publisher": {
"@type": "Organization",
"name": "UK Data Services",
"logo": {
"@type": "ImageObject",
"url": "https://ukdataservices.co.uk/assets/images/logo.svg"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://ukdataservices.co.uk/blog/articles/<?php echo $article_slug; ?>"
},
"keywords": "<?php echo htmlspecialchars($article_keywords); ?>"
}
</script>
</head>
<body>
<?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/nav.php'); ?>
<article class="blog-article">
<div class="container">
<div class="article-meta">
<span class="category"><a href="/blog/categories/technology.php">Technology</a></span>
<time datetime="2024-06-04">4 June 2024</time>
<span class="read-time">6 min read</span>
</div>
<header class="article-header">
<h1><?php echo htmlspecialchars($article_title); ?></h1>
<p class="article-lead"><?php echo htmlspecialchars($article_description); ?></p>
</header>
<div class="article-content">
<section>
<h2>The Evolution of Python Data Pipeline Tools</h2>
<p>The Python data engineering ecosystem has matured significantly in 2025, with new tools emerging and established frameworks evolving to meet the demands of modern data infrastructure. As organisations handle increasingly complex data workflows, the choice of pipeline orchestration tools has become critical for scalability, maintainability, and operational efficiency.</p>
<p>Key trends shaping the data pipeline landscape:</p>
<ul>
<li><strong>Cloud-Native Architecture:</strong> Tools designed specifically for cloud environments and containerised deployments</li>
<li><strong>Developer Experience:</strong> Focus on intuitive APIs, better debugging, and improved testing capabilities</li>
<li><strong>Observability:</strong> Enhanced monitoring, logging, and data lineage tracking</li>
<li><strong>Real-Time Processing:</strong> Integration of batch and streaming processing paradigms</li>
<li><strong>DataOps Integration:</strong> CI/CD practices and infrastructure-as-code approaches</li>
</ul>
<p>The modern data pipeline tool must balance ease of use with enterprise-grade features, supporting everything from simple ETL jobs to complex machine learning workflows, including <a href="/blog/articles/predictive-analytics-customer-churn">customer churn prediction pipelines</a>.</p>
</section>
<section>
<h2>Apache Airflow: The Established Leader</h2>
<h3>Overview and Market Position</h3>
<p>Apache Airflow remains the most widely adopted workflow orchestration platform, with over 30,000 GitHub stars and extensive enterprise adoption. Developed by Airbnb and now an Apache Software Foundation project, Airflow has proven its scalability and reliability in production environments.</p>
<h3>Key Strengths</h3>
<ul>
<li><strong>Mature Ecosystem:</strong> Extensive library of pre-built operators and hooks</li>
<li><strong>Enterprise Features:</strong> Role-based access control, audit logging, and extensive configuration options</li>
<li><strong>Community Support:</strong> Large community with extensive documentation and tutorials</li>
<li><strong>Integration Capabilities:</strong> Native connectors for major cloud platforms and data tools</li>
<li><strong>Scalability:</strong> Proven ability to handle thousands of concurrent tasks</li>
</ul>
<h3>2025 Developments</h3>
<p>Airflow 2.8+ introduces several significant improvements:</p>
<ul>
<li><strong>Enhanced UI:</strong> Modernised web interface with improved performance and usability</li>
<li><strong>Dynamic Task Mapping:</strong> Runtime task generation for complex workflows</li>
<li><strong>TaskFlow API:</strong> Simplified DAG authoring with Python decorators</li>
<li><strong>Kubernetes Integration:</strong> Improved KubernetesExecutor and Kubernetes Operator</li>
<li><strong>Data Lineage:</strong> Built-in lineage tracking and data quality monitoring</li>
</ul>
<h3>Best Use Cases</h3>
<ul>
<li>Complex enterprise data workflows with multiple dependencies</li>
<li>Organisations requiring extensive integration with existing tools</li>
<li>Teams with strong DevOps capabilities for managing infrastructure</li>
<li>Workflows requiring detailed audit trails and compliance features</li>
</ul>
</section>
<section>
<h2>Prefect: Modern Python-First Approach</h2>
<h3>Overview and Philosophy</h3>
<p>Prefect represents a modern approach to workflow orchestration, designed from the ground up with Python best practices and developer experience in mind. Founded by former Airflow contributors, Prefect addresses many of the pain points associated with traditional workflow tools.</p>
<h3>Key Innovations</h3>
<ul>
<li><strong>Hybrid Execution Model:</strong> Separation of orchestration and execution layers</li>
<li><strong>Python-Native:</strong> True Python functions without custom operators</li>
<li><strong>Automatic Retries:</strong> Intelligent retry logic with exponential backoff</li>
<li><strong>State Management:</strong> Advanced state tracking and recovery mechanisms</li>
<li><strong>Cloud-First Design:</strong> Built for cloud deployment and managed services</li>
</ul>
<h3>Prefect 2.0 Features</h3>
<p>The latest version introduces significant architectural improvements:</p>
<ul>
<li><strong>Simplified Deployment:</strong> Single-command deployment to various environments</li>
<li><strong>Subflows:</strong> Composable workflow components for reusability</li>
<li><strong>Concurrent Task Execution:</strong> Async/await support for high-performance workflows</li>
<li><strong>Dynamic Workflows:</strong> Runtime workflow generation based on data</li>
<li><strong>Enhanced Observability:</strong> Comprehensive logging and monitoring capabilities</li>
</ul>
<h3>Best Use Cases</h3>
<ul>
<li>Data science and machine learning workflows</li>
<li>Teams prioritising developer experience and rapid iteration</li>
<li>Cloud-native organisations using managed services</li>
<li>Projects requiring flexible deployment models</li>
</ul>
</section>
<section>
<h2>Dagster: Asset-Centric Data Orchestration</h2>
<h3>The Asset-Centric Philosophy</h3>
<p>Dagster introduces a fundamentally different approach to data orchestration by focusing on data assets rather than tasks. This asset-centric model provides better data lineage, testing capabilities, and overall data quality management.</p>
<h3>Core Concepts</h3>
<ul>
<li><strong>Software-Defined Assets:</strong> Data assets as first-class citizens in pipeline design</li>
<li><strong>Type System:</strong> Strong typing for data validation and documentation</li>
<li><strong>Resource Management:</strong> Clean separation of business logic and infrastructure</li>
<li><strong>Testing Framework:</strong> Built-in testing capabilities for data pipelines</li>
<li><strong>Materialisation:</strong> Explicit tracking of when and how data is created</li>
</ul>
<h3>Enterprise Features</h3>
<p>Dagster Cloud and open-source features for enterprise adoption:</p>
<ul>
<li><strong>Data Quality:</strong> Built-in data quality checks and expectations</li>
<li><strong>Lineage Tracking:</strong> Automatic lineage generation across entire data ecosystem</li>
<li><strong>Version Control:</strong> Git integration for pipeline versioning and deployment</li>
<li><strong>Alert Management:</strong> Intelligent alerting based on data quality and pipeline health</li>
<li><strong>Cost Optimisation:</strong> Resource usage tracking and optimisation recommendations</li>
</ul>
<h3>Best Use Cases</h3>
<ul>
<li>Data teams focused on data quality and governance</li>
<li>Organisations with complex data lineage requirements</li>
<li>Analytics workflows with multiple data consumers</li>
<li>Teams implementing data mesh architectures</li>
</ul>
</section>
<section>
<h2>Emerging Tools and Technologies</h2>
<h3>Kedro: Reproducible Data Science Pipelines</h3>
<p>Developed by QuantumBlack (McKinsey), Kedro focuses on creating reproducible and maintainable data science pipelines:</p>
<ul>
<li><strong>Pipeline Modularity:</strong> Standardised project structure and reusable components</li>
<li><strong>Data Catalog:</strong> Unified interface for data access across multiple sources</li>
<li><strong>Configuration Management:</strong> Environment-specific configurations and parameter management</li>
<li><strong>Visualisation:</strong> Pipeline visualisation and dependency mapping</li>
</ul>
<h3>Flyte: Kubernetes-Native Workflows</h3>
<p>Flyte provides cloud-native workflow orchestration with strong focus on reproducibility:</p>
<ul>
<li><strong>Container-First:</strong> Every task runs in its own container environment</li>
<li><strong>Multi-Language Support:</strong> Python, Java, Scala workflows in unified platform</li>
<li><strong>Resource Management:</strong> Automatic resource allocation and scaling</li>
<li><strong>Reproducibility:</strong> Immutable workflow versions and execution tracking</li>
</ul>
<h3>Metaflow: Netflix's ML Platform</h3>
<p>Open-sourced by Netflix, Metaflow focuses on machine learning workflow orchestration:</p>
<ul>
<li><strong>Experiment Tracking:</strong> Automatic versioning and experiment management</li>
<li><strong>Cloud Integration:</strong> Seamless AWS and Azure integration</li>
<li><strong>Scaling:</strong> Automatic scaling from laptop to cloud infrastructure</li>
<li><strong>Collaboration:</strong> Team-oriented features for ML development</li>
</ul>
</section>
<section>
<h2>Tool Comparison and Selection Criteria</h2>
<h3>Feature Comparison Matrix</h3>
<p>Key factors to consider when selecting a data pipeline tool:</p>
<table class="comparison-table">
<thead>
<tr>
<th>Feature</th>
<th>Airflow</th>
<th>Prefect</th>
<th>Dagster</th>
<th>Kedro</th>
</tr>
</thead>
<tbody>
<tr>
<td>Learning Curve</td>
<td>Steep</td>
<td>Moderate</td>
<td>Moderate</td>
<td>Gentle</td>
</tr>
<tr>
<td>Enterprise Readiness</td>
<td>Excellent</td>
<td>Good</td>
<td>Good</td>
<td>Moderate</td>
</tr>
<tr>
<td>Cloud Integration</td>
<td>Good</td>
<td>Excellent</td>
<td>Excellent</td>
<td>Good</td>
</tr>
<tr>
<td>Data Lineage</td>
<td>Basic</td>
<td>Good</td>
<td>Excellent</td>
<td>Basic</td>
</tr>
<tr>
<td>Testing Support</td>
<td>Basic</td>
<td>Good</td>
<td>Excellent</td>
<td>Excellent</td>
</tr>
</tbody>
</table>
<h3>Decision Framework</h3>
<p>Consider these factors when choosing a tool:</p>
<ul>
<li><strong>Team Size and Skills:</strong> Available DevOps expertise and Python proficiency</li>
<li><strong>Infrastructure:</strong> On-premises, cloud, or hybrid deployment requirements</li>
<li><strong>Workflow Complexity:</strong> Simple ETL vs. complex ML workflows</li>
<li><strong>Compliance Requirements:</strong> Audit trails, access control, and governance needs</li>
<li><strong>Scalability Needs:</strong> Current and projected data volumes and processing requirements</li>
<li><strong>Integration Requirements:</strong> Existing tool ecosystem and API connectivity</li>
</ul>
</section>
<section>
<h2>Implementation Best Practices</h2>
<h3>Infrastructure Considerations</h3>
<ul>
<li><strong>Containerisation:</strong> Use Docker containers for consistent execution environments</li>
<li><strong>Secret Management:</strong> Implement secure credential storage and rotation</li>
<li><strong>Resource Allocation:</strong> Plan compute and memory requirements for peak loads</li>
<li><strong>Network Security:</strong> Configure VPCs, firewalls, and access controls</li>
<li><strong>Monitoring:</strong> Implement comprehensive observability and alerting</li>
</ul>
<h3>Development Practices</h3>
<ul>
<li><strong>Version Control:</strong> Store pipeline code in Git with proper branching strategies</li>
<li><strong>Testing:</strong> Implement unit tests, integration tests, and data quality checks</li>
<li><strong>Documentation:</strong> Maintain comprehensive documentation for workflows and data schemas</li>
<li><strong>Code Quality:</strong> Use linting, formatting, and code review processes</li>
<li><strong>Environment Management:</strong> Separate development, staging, and production environments</li>
</ul>
<h3>Operational Excellence</h3>
<ul>
<li><strong>Monitoring:</strong> Track pipeline performance, data quality, and system health</li>
<li><strong>Alerting:</strong> Configure intelligent alerts for failures and anomalies</li>
<li><strong>Backup and Recovery:</strong> Implement data backup and disaster recovery procedures</li>
<li><strong>Performance Optimisation:</strong> Regular performance tuning and resource optimisation</li>
<li><strong>Security:</strong> Regular security audits and vulnerability assessments</li>
</ul>
</section>
<section>
<h2>Future Trends and Predictions</h2>
<h3>Emerging Patterns</h3>
<p>Several trends are shaping the future of data pipeline tools:</p>
<ul>
<li><strong>Serverless Orchestration:</strong> Function-as-a-Service integration for cost-effective scaling</li>
<li><strong>AI-Powered Optimisation:</strong> Machine learning for automatic performance tuning</li>
<li><strong>Low-Code/No-Code:</strong> Visual pipeline builders for business users</li>
<li><strong>Real-Time Integration:</strong> Unified batch and streaming processing</li>
<li><strong>Data Mesh Support:</strong> Decentralised data architecture capabilities</li>
</ul>
<h3>Technology Convergence</h3>
<p>The boundaries between different data tools continue to blur:</p>
<ul>
<li><strong>MLOps Integration:</strong> Tighter integration with ML lifecycle management</li>
<li><strong>Data Quality Integration:</strong> Built-in data validation and quality monitoring</li>
<li><strong>Catalogue Integration:</strong> Native data catalogue and lineage capabilities</li>
<li><strong>Governance Features:</strong> Policy enforcement and compliance automation</li>
</ul>
</section>
<section class="article-cta">
<h2>Expert Data Pipeline Implementation</h2>
<p>Choosing and implementing the right data pipeline tools requires deep understanding of both technology capabilities and business requirements. UK Data Services provides comprehensive consulting services for data pipeline architecture, tool selection, and implementation to help organisations build robust, scalable data infrastructure.</p>
<a href="/#contact" class="cta-button">Get Pipeline Consultation</a>
</section>
</div>
<?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/author-bio.php'); ?>
<?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/article-footer.php'); ?>
</div>
</article>
<?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php'); ?>
<script src="/assets/js/main.js" defer></script>
<script src="../../assets/js/cro-enhancements.js"></script>
</body>
</html>

View File

@@ -152,7 +152,7 @@ $modified_date = "2025-08-08";
<time datetime="<?php echo $published_date; ?>"><?php echo date('j F Y', strtotime($published_date)); ?></time> <time datetime="<?php echo $published_date; ?>"><?php echo date('j F Y', strtotime($published_date)); ?></time>
<span class="read-time">15 min read</span> <span class="read-time">15 min read</span>
</div> </div>
<h1>Web Scraping Services UK: Complete 2025 Buyer's Guide</h1> <h1><a href="/services/web-scraping.php" title="UK web scraping services">Web Scraping Services</a> UK: Complete 2025 Buyer's Guide</h1>
<p class="article-subtitle">Navigate the UK web scraping market with confidence. Compare providers, understand pricing, and find the perfect data extraction partner for your business needs.</p> <p class="article-subtitle">Navigate the UK web scraping market with confidence. Compare providers, understand pricing, and find the perfect data extraction partner for your business needs.</p>
<div class="article-author"> <div class="article-author">
<span>By UK Data Services Editorial Team</span> <span>By UK Data Services Editorial Team</span>
@@ -199,9 +199,9 @@ $modified_date = "2025-08-08";
<h3>Market Drivers</h3> <h3>Market Drivers</h3>
<ul> <ul>
<li><strong>Digital Transformation:</strong> UK businesses prioritizing data-driven decision making</li> <li><strong>Digital Transformation:</strong> UK businesses prioritizing data-driven decision making</li>
<li><strong>Competitive Intelligence:</strong> Real-time market monitoring becoming essential</li> <li><strong><a href="/services/competitive-intelligence.php" title="competitive intelligence services UK">Competitive Intelligence</a>:</strong> Real-time market monitoring becoming essential</li>
<li><strong>Regulatory Compliance:</strong> GDPR-compliant data collection requirements</li> <li><strong>Regulatory Compliance:</strong> GDPR-compliant data collection requirements</li>
<li><strong>E-commerce Growth:</strong> Price monitoring and competitor analysis demand</li> <li><strong>E-commerce Growth:</strong> <a href="/services/price-monitoring.php" title="competitor price monitoring UK">Price monitoring</a> and competitor analysis demand</li>
<li><strong>Financial Services:</strong> Alternative data sources for investment decisions</li> <li><strong>Financial Services:</strong> Alternative data sources for investment decisions</li>
</ul> </ul>
</section> </section>

View File

@@ -1,218 +0,0 @@
<?php
/**
* Author Bio Component
* Include this in blog articles to display author information with E-E-A-T signals
*
* Required variables:
* - $article_author (string): Author name
*
* Optional variables:
* - $author_role (string): Author's job title
* - $author_bio (string): Short bio description
* - $author_linkedin (string): LinkedIn URL
*/
// Author database with credentials and bios
$authors = [
'UK Data Services Editorial Team' => [
'role' => 'Data Intelligence Experts',
'bio' => 'Our editorial team comprises data scientists, engineers, and industry analysts with over 50 combined years of experience in web scraping, data analytics, and business intelligence across UK industries.',
'linkedin' => null,
'expertise' => ['Web Scraping', 'Data Analytics', 'Business Intelligence', 'GDPR Compliance'],
'image' => '/assets/images/authors/team-avatar.svg'
],
'James Wilson' => [
'role' => 'Senior Data Architect',
'bio' => 'James is a Senior Data Architect with 12+ years of experience in enterprise web scraping and business intelligence. He holds a Master\'s degree in Computer Science from Imperial College London and is an AWS Solutions Architect Professional.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Enterprise Architecture', 'Web Scraping', 'Cloud Solutions', 'Data Pipelines'],
'image' => '/assets/images/authors/james-wilson.svg'
],
'Dr. Rachel Singh' => [
'role' => 'Lead Data Scientist',
'bio' => 'Dr. Rachel Singh leads our data science team with expertise in machine learning and AI-powered data extraction. She holds a PhD in Computer Science from University of Cambridge and has published research on NLP and intelligent document processing.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Machine Learning', 'NLP', 'AI', 'Computer Vision'],
'image' => '/assets/images/authors/rachel-singh.svg'
],
'Michael Thompson' => [
'role' => 'Technical Lead - Web Scraping',
'bio' => 'Michael specializes in large-scale web scraping infrastructure and has designed data collection systems for FTSE 100 companies. He has 10+ years of experience in Python, Scrapy, and distributed systems.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Python', 'Scrapy', 'Distributed Systems', 'Web Scraping'],
'image' => '/assets/images/authors/michael-thompson.svg'
],
'Sarah Chen' => [
'role' => 'Compliance & Data Protection Officer',
'bio' => 'Sarah is a certified Data Protection Officer (GDPR-P) with extensive experience in UK and EU data regulations. She ensures all our data collection practices meet the highest compliance standards.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['GDPR', 'Data Protection', 'Compliance', 'Privacy'],
'image' => '/assets/images/authors/sarah-chen.svg'
],
'David Martinez' => [
'role' => 'Business Intelligence Consultant',
'bio' => 'David is a certified Tableau and Power BI consultant with 8+ years of experience helping UK businesses transform raw data into actionable insights. He specializes in dashboard design and data visualization.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Tableau', 'Power BI', 'Data Visualization', 'BI Strategy'],
'image' => '/assets/images/authors/david-martinez.svg'
],
'Emma Richardson' => [
'role' => 'Industry Analyst',
'bio' => 'Emma covers UK market trends and industry analysis with a focus on retail, property, and e-commerce sectors. She has over 6 years of experience in competitive intelligence and market research.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Market Research', 'Competitive Intelligence', 'E-commerce', 'Retail Analytics'],
'image' => '/assets/images/authors/emma-richardson.svg'
]
];
// Get author info
$author_name = isset($article_author) ? $article_author : 'UK Data Services Editorial Team';
$author_info = isset($authors[$author_name]) ? $authors[$author_name] : $authors['UK Data Services Editorial Team'];
?>
<div class="author-bio" itemscope itemtype="https://schema.org/Person">
<div class="author-avatar">
<img src="<?php echo htmlspecialchars($author_info['image']); ?>"
alt="<?php echo htmlspecialchars($author_name); ?>"
loading="lazy"
width="80"
height="80"
itemprop="image">
</div>
<div class="author-info">
<h4 class="author-header">About the Author</h4>
<p class="author-name" itemprop="name"><?php echo htmlspecialchars($author_name); ?></p>
<p class="author-role" itemprop="jobTitle"><?php echo htmlspecialchars($author_info['role']); ?></p>
<p class="author-description" itemprop="description"><?php echo htmlspecialchars($author_info['bio']); ?></p>
<div class="author-expertise">
<span class="expertise-label">Expertise:</span>
<?php foreach ($author_info['expertise'] as $skill): ?>
<span class="expertise-tag"><?php echo htmlspecialchars($skill); ?></span>
<?php endforeach; ?>
</div>
<?php if ($author_info['linkedin']): ?>
<div class="author-social">
<a href="<?php echo htmlspecialchars($author_info['linkedin']); ?>"
target="_blank"
rel="noopener noreferrer"
itemprop="sameAs"
class="linkedin-link">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
</svg>
Connect on LinkedIn
</a>
</div>
<?php endif; ?>
</div>
</div>
<style>
.author-bio {
display: flex;
gap: 20px;
padding: 24px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 12px;
margin: 40px 0;
border-left: 4px solid #179e83;
}
.author-avatar img {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
border: 3px solid #179e83;
}
.author-info {
flex: 1;
}
.author-header {
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.5px;
color: #144784;
margin: 0 0 8px 0;
font-weight: 600;
}
.author-name {
font-size: 1.25rem;
font-weight: 700;
color: #1a1a1a;
margin: 0 0 4px 0;
}
.author-role {
font-size: 0.95rem;
color: #666;
margin: 0 0 12px 0;
font-weight: 500;
}
.author-description {
font-size: 0.95rem;
color: #444;
line-height: 1.6;
margin: 0 0 16px 0;
}
.author-expertise {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin-bottom: 12px;
}
.expertise-label {
font-size: 0.85rem;
font-weight: 600;
color: #555;
}
.expertise-tag {
font-size: 0.8rem;
padding: 4px 10px;
background: #fff;
border: 1px solid #ddd;
border-radius: 16px;
color: #555;
}
.author-social .linkedin-link {
display: inline-flex;
align-items: center;
gap: 6px;
color: #0077b5;
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
transition: color 0.2s;
}
.author-social .linkedin-link:hover {
color: #005885;
text-decoration: underline;
}
@media (max-width: 600px) {
.author-bio {
flex-direction: column;
text-align: center;
}
.author-avatar {
margin: 0 auto;
}
.author-expertise {
justify-content: center;
}
}
</style>

View File

@@ -1,52 +0,0 @@
<?php
/**
* Breadcrumb Schema Component
* Generates BreadcrumbList structured data for improved SEO
*
* Usage: Set $breadcrumbs array before including this file
* Example:
* $breadcrumbs = [
* ['url' => '/', 'label' => 'Home'],
* ['url' => '/blog', 'label' => 'Blog'],
* ['url' => '', 'label' => 'Current Page Title']
* ];
*/
if (!isset($breadcrumbs) || empty($breadcrumbs)) {
return;
}
$base_url = 'https://ukdataservices.co.uk';
$items = [];
foreach ($breadcrumbs as $index => $crumb) {
$position = $index + 1;
$item = [
'@type' => 'ListItem',
'position' => $position,
'name' => $crumb['label']
];
// Add URL for all items except the last one (current page)
if (!empty($crumb['url'])) {
$url = $crumb['url'];
// Ensure URL is absolute
if (strpos($url, 'http') !== 0) {
$url = $base_url . $url;
}
$item['item'] = $url;
}
$items[] = $item;
}
$schema = [
'@context' => 'https://schema.org',
'@type' => 'BreadcrumbList',
'itemListElement' => $items
];
?>
<script type="application/ld+json">
<?php echo json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); ?>
</script>

View File

@@ -1,160 +0,0 @@
<?php
/**
* Canonical URL Helper
* Generates consistent canonical URLs for the site
*
* Usage:
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/canonical.php');
* $canonical = getCanonicalUrl();
*/
/**
* Get the canonical URL for the current page
* Handles www/non-www, http/https, trailing slashes, and query strings
*
* @param string|null $overrideUrl Optional URL to override auto-detection
* @return string The canonical URL
*/
function getCanonicalUrl($overrideUrl = null) {
$baseUrl = 'https://ukdataservices.co.uk';
// If override provided, clean and return it
if ($overrideUrl) {
return cleanCanonicalUrl($baseUrl, $overrideUrl);
}
// Auto-detect current URL
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
// Remove query string
$path = parse_url($requestUri, PHP_URL_PATH);
// Remove .php extension for clean URLs
if (substr($path, -4) === '.php') {
$path = substr($path, 0, -4);
}
// Normalize trailing slashes (remove except for root)
if ($path !== '/' && substr($path, -1) === '/') {
$path = rtrim($path, '/');
}
return $baseUrl . $path;
}
/**
* Clean and normalize a canonical URL
*
* @param string $baseUrl The site base URL
* @param string $url The URL to clean
* @return string Cleaned canonical URL
*/
function cleanCanonicalUrl($baseUrl, $url) {
// If it's a relative URL, make it absolute
if (strpos($url, 'http') !== 0) {
$url = $baseUrl . '/' . ltrim($url, '/');
}
// Remove query string
$url = strtok($url, '?');
// Remove .php extension
if (substr($url, -4) === '.php') {
$url = substr($url, 0, -4);
}
// Normalize trailing slashes
$path = parse_url($url, PHP_URL_PATH);
if ($path && $path !== '/' && substr($path, -1) === '/') {
$url = rtrim($url, '/');
}
// Ensure https and non-www
$url = str_replace('http://', 'https://', $url);
$url = str_replace('://www.', '://', $url);
return $url;
}
/**
* Generate the canonical link tag
*
* @param string|null $url Optional URL override
* @return string HTML link tag
*/
function generateCanonicalTag($url = null) {
$canonical = getCanonicalUrl($url);
return '<link rel="canonical" href="' . htmlspecialchars($canonical) . '">';
}
/**
* Get URL for a specific page by key
*
* @param string $pageKey The page identifier
* @return string The full canonical URL
*/
function getPageUrl($pageKey) {
$baseUrl = 'https://ukdataservices.co.uk';
$urls = [
'home' => '',
'about' => '/about',
'quote' => '/quote',
'faq' => '/faq',
'blog' => '/blog',
'contact' => '/#contact',
'privacy' => '/privacy-policy',
'terms' => '/terms-of-service',
'cookies' => '/cookie-policy',
'gdpr' => '/gdpr-compliance',
'project-types' => '/project-types',
'case-studies' => '/case-studies',
// Services
'services' => '/#services',
'web-scraping' => '/services/web-scraping',
'competitive-intelligence' => '/services/competitive-intelligence',
'price-monitoring' => '/services/price-monitoring',
'data-cleaning' => '/services/data-cleaning',
'data-analytics' => '/services/data-analytics',
'api-development' => '/services/api-development',
'property-data' => '/services/property-data-extraction',
'financial-data' => '/services/financial-data-services',
// Locations
'london' => '/locations/london',
'manchester' => '/locations/manchester',
'birmingham' => '/locations/birmingham',
'edinburgh' => '/locations/edinburgh',
'cardiff' => '/locations/cardiff'
];
$path = $urls[$pageKey] ?? '';
return $baseUrl . $path;
}
/**
* Check if current page is the canonical version
*
* @return bool True if current URL is canonical
*/
function isCanonicalUrl() {
$currentUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
. "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$canonical = getCanonicalUrl();
return cleanCanonicalUrl('https://ukdataservices.co.uk', $currentUrl) === $canonical;
}
/**
* Output redirect to canonical URL if needed
* Call this at the very beginning of pages before any output
*/
function enforceCanonicalUrl() {
if (!isCanonicalUrl()) {
$canonical = getCanonicalUrl();
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $canonical);
exit;
}
}

View File

@@ -1,225 +0,0 @@
<?php
/**
* Location CTA Component
* Displays location links at the bottom of service pages
*
* Usage:
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/components/location-cta.php');
* Or: displayLocationCTA();
*/
// Include URL config if not already loaded
if (!isset($locationData)) {
include($_SERVER['DOCUMENT_ROOT'] . '/includes/url-config.php');
}
/**
* Display location CTA section
*
* @param string|null $serviceName Optional service name to customize the message
*/
function displayLocationCTA($serviceName = null) {
global $locationData;
$serviceText = $serviceName ? htmlspecialchars($serviceName) . ' services' : 'data services';
?>
<section class="location-cta">
<div class="container">
<div class="location-cta-content">
<h2>Serving Businesses Across the UK</h2>
<p>We provide professional <?php echo $serviceText; ?> to businesses throughout the United Kingdom, with dedicated support for major business centres.</p>
<div class="location-links">
<?php foreach ($locationData as $key => $location): ?>
<a href="<?php echo htmlspecialchars($location['url']); ?>" class="location-link">
<span class="location-icon">
<?php echo getLocationIcon($key); ?>
</span>
<span class="location-name"><?php echo htmlspecialchars($location['title']); ?></span>
<span class="location-region"><?php echo htmlspecialchars($location['region']); ?></span>
</a>
<?php endforeach; ?>
</div>
<div class="location-cta-footer">
<p>Not in one of these locations? We serve businesses throughout the UK with remote data services.</p>
<a href="/quote" class="btn btn-primary">Request a Consultation</a>
</div>
</div>
</div>
</section>
<style>
.location-cta {
padding: 80px 0;
background: linear-gradient(135deg, #144784 0%, #1a5a9e 100%);
color: white;
}
.location-cta-content {
text-align: center;
max-width: 1000px;
margin: 0 auto;
}
.location-cta h2 {
font-size: 2rem;
margin-bottom: 15px;
}
.location-cta > .container > .location-cta-content > p {
font-size: 1.1rem;
opacity: 0.9;
margin-bottom: 40px;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.location-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
margin-bottom: 40px;
}
.location-link {
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
border-radius: 12px;
padding: 20px 30px;
text-decoration: none;
color: white;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
min-width: 150px;
}
.location-link:hover {
background: rgba(255,255,255,0.2);
transform: translateY(-3px);
}
.location-icon {
font-size: 1.5rem;
margin-bottom: 10px;
}
.location-name {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 5px;
}
.location-region {
font-size: 0.85rem;
opacity: 0.8;
}
.location-cta-footer {
padding-top: 30px;
border-top: 1px solid rgba(255,255,255,0.2);
}
.location-cta-footer p {
margin-bottom: 20px;
opacity: 0.9;
}
.location-cta .btn-primary {
background: #179e83;
color: white;
padding: 14px 32px;
border-radius: 8px;
text-decoration: none;
font-weight: 500;
display: inline-block;
transition: all 0.3s ease;
}
.location-cta .btn-primary:hover {
background: #14876f;
transform: translateY(-2px);
}
@media (max-width: 768px) {
.location-cta {
padding: 60px 20px;
}
.location-links {
flex-direction: column;
align-items: center;
}
.location-link {
width: 100%;
max-width: 250px;
}
}
</style>
<?php
}
/**
* Get location icon based on city
*/
function getLocationIcon($locationKey) {
$icons = [
'london' => '🏙️',
'manchester' => '🏭',
'birmingham' => '🏛️',
'edinburgh' => '🏴󠁧󠁢󠁳󠁣󠁴󠁿',
'cardiff' => '🏴󠁧󠁢󠁷󠁬󠁳󠁿'
];
return $icons[$locationKey] ?? '📍';
}
/**
* Display compact location links (for footers or sidebars)
*/
function displayCompactLocationLinks() {
global $locationData;
?>
<div class="compact-locations">
<span class="compact-locations-label">Serving:</span>
<?php
$locations = array_keys($locationData);
foreach ($locations as $index => $key):
$location = $locationData[$key];
?>
<a href="<?php echo htmlspecialchars($location['url']); ?>"><?php echo htmlspecialchars($location['title']); ?></a><?php echo $index < count($locations) - 1 ? ', ' : ''; ?>
<?php endforeach; ?>
<span class="compact-locations-suffix">and the UK</span>
</div>
<style>
.compact-locations {
font-size: 0.9rem;
color: #666;
}
.compact-locations a {
color: #179e83;
text-decoration: none;
}
.compact-locations a:hover {
text-decoration: underline;
}
.compact-locations-label,
.compact-locations-suffix {
color: #888;
}
</style>
<?php
}
// Auto-display if this file is included directly without function call
if (basename($_SERVER['SCRIPT_FILENAME']) === 'location-cta.php') {
displayLocationCTA();
}

View File

@@ -1,152 +0,0 @@
<?php
/**
* Related Services Component
* Displays related services at the bottom of service pages
*
* Usage:
* $currentService = 'web-scraping';
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/components/related-services.php');
*/
// Include URL config if not already loaded
if (!isset($serviceData)) {
include($_SERVER['DOCUMENT_ROOT'] . '/includes/url-config.php');
}
/**
* Display related services section
*
* @param string $currentService Current service key
* @param int $maxServices Maximum number of related services to show
*/
function displayRelatedServices($currentService, $maxServices = 3) {
global $serviceData, $relatedServices;
$related = $relatedServices[$currentService] ?? [];
if (empty($related)) {
return;
}
// Limit to max services
$related = array_slice($related, 0, $maxServices);
?>
<section class="related-services">
<div class="container">
<h2>Related Services</h2>
<p class="section-intro">Explore our other data services that complement <?php echo htmlspecialchars($serviceData[$currentService]['shortTitle'] ?? 'this service'); ?>.</p>
<div class="related-services-grid">
<?php foreach ($related as $serviceKey): ?>
<?php if (isset($serviceData[$serviceKey])): ?>
<?php $service = $serviceData[$serviceKey]; ?>
<a href="<?php echo htmlspecialchars($service['url']); ?>" class="related-service-card">
<div class="service-icon">
<?php if (isset($service['icon'])): ?>
<img src="/assets/images/<?php echo htmlspecialchars($service['icon']); ?>"
alt="<?php echo htmlspecialchars($service['title']); ?>"
loading="lazy">
<?php endif; ?>
</div>
<h3><?php echo htmlspecialchars($service['title']); ?></h3>
<p><?php echo htmlspecialchars($service['description']); ?></p>
<span class="learn-more">Learn More &rarr;</span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</section>
<style>
.related-services {
padding: 80px 0;
background: #f8f9fa;
}
.related-services h2 {
text-align: center;
font-size: 2rem;
color: #144784;
margin-bottom: 15px;
}
.related-services .section-intro {
text-align: center;
color: #666;
max-width: 600px;
margin: 0 auto 40px;
}
.related-services-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
max-width: 1000px;
margin: 0 auto;
}
.related-service-card {
background: white;
padding: 30px;
border-radius: 12px;
text-decoration: none;
color: inherit;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
transition: all 0.3s ease;
display: block;
}
.related-service-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.related-service-card .service-icon {
width: 60px;
height: 60px;
margin-bottom: 20px;
}
.related-service-card .service-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.related-service-card h3 {
font-size: 1.25rem;
color: #144784;
margin-bottom: 10px;
}
.related-service-card p {
color: #666;
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 15px;
}
.related-service-card .learn-more {
color: #179e83;
font-weight: 500;
font-size: 0.9rem;
}
@media (max-width: 768px) {
.related-services {
padding: 60px 20px;
}
.related-services-grid {
grid-template-columns: 1fr;
}
}
</style>
<?php
}
// Auto-display if $currentService is set
if (isset($currentService)) {
displayRelatedServices($currentService);
}

View File

@@ -1,162 +0,0 @@
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-section">
<div class="footer-logo">
<img src="/assets/images/logo-white.svg" alt="UK Data Services" loading="lazy">
</div>
<p>Enterprise data intelligence solutions for modern British business. Transform your operations with accurate, actionable insights and regulatory-compliant data services.</p>
</div>
<div class="footer-section">
<h3>Our Services</h3>
<ul>
<li><a href="/services/web-scraping">Web Scraping</a></li>
<li><a href="/services/competitive-intelligence">Competitive Intelligence</a></li>
<li><a href="/services/price-monitoring">Price Monitoring</a></li>
<li><a href="/services/data-cleaning">Data Cleaning</a></li>
<li><a href="/services/property-data-extraction">Property Data</a></li>
<li><a href="/services/financial-data-services">Financial Data</a></li>
</ul>
</div>
<div class="footer-section">
<h3>Locations</h3>
<ul>
<li><a href="/locations/london">London</a></li>
<li><a href="/locations/manchester">Manchester</a></li>
<li><a href="/locations/birmingham">Birmingham</a></li>
</ul>
</div>
<div class="footer-section">
<h3>Resources & Insights</h3>
<ul>
<li><a href="/tools/">Free Tools</a></li>
<li><a href="/blog/">Data Intelligence Blog</a></li>
<li><a href="/case-studies/">Case Studies</a></li>
<li><a href="/about">About UK Data Services</a></li>
<li><a href="/project-types">Project Types</a></li>
<li><a href="/faq">FAQ</a></li>
<li><a href="/quote">Request Consultation</a></li>
</ul>
</div>
<div class="footer-section">
<h3>Legal</h3>
<ul>
<li><a href="/privacy-policy">Privacy Policy</a></li>
<li><a href="/terms-of-service">Terms of Service</a></li>
<li><a href="/cookie-policy">Cookie Policy</a></li>
<li><a href="/gdpr-compliance">GDPR Compliance</a></li>
</ul>
</div>
</div>
<!-- Trust Badges -->
<div class="footer-trust-badges">
<div class="trust-badges-container">
<div class="trust-badge">
<div class="trust-badge-icon">🔒</div>
<div class="trust-badge-text">
<strong>GDPR Compliant</strong>
<span>Full UK data protection compliance</span>
</div>
</div>
<div class="trust-badge">
<div class="trust-badge-icon">📋</div>
<div class="trust-badge-text">
<span>Registration: ZA123456</span>
</div>
</div>
<div class="trust-badge">
<div class="trust-badge-icon">🛡️</div>
<div class="trust-badge-text">
<span>UK Government backed scheme</span>
</div>
</div>
<div class="trust-badge">
<div class="trust-badge-icon">🇬🇧</div>
<div class="trust-badge-text">
<strong>UK Based</strong>
<span>British owned and operated</span>
</div>
</div>
</div>
</div>
<div class="footer-bottom">
<div class="footer-bottom-content">
<div class="footer-copyright">
<p>&copy; <?php echo date('Y'); ?> UK Data Services. All rights reserved.</p>
<p class="company-details">
Company No: 12345678 | VAT No: GB123456789 | ICO Registration: ZA123456
</p>
</div>
<div class="social-links">
<a href="https://linkedin.com/company/uk-data-services" aria-label="LinkedIn" target="_blank" rel="noopener noreferrer"><img src="/assets/images/icon-linkedin.svg" alt="LinkedIn" loading="lazy"></a>
<a href="https://twitter.com/ukdataservices" aria-label="Twitter" target="_blank" rel="noopener noreferrer"><img src="/assets/images/icon-twitter.svg" alt="Twitter" loading="lazy"></a>
</div>
</div>
</div>
</div>
</footer>
<style>
.footer-trust-badges {
border-top: 1px solid rgba(255,255,255,0.1);
border-bottom: 1px solid rgba(255,255,255,0.1);
padding: 30px 0;
margin: 30px 0;
}
.trust-badges-container {
display: flex;
justify-content: center;
gap: 40px;
flex-wrap: wrap;
}
.trust-badge {
display: flex;
align-items: center;
gap: 12px;
}
.trust-badge-icon {
font-size: 2rem;
}
.trust-badge-text {
text-align: left;
}
.trust-badge-text strong {
display: block;
color: #fff;
font-size: 0.95rem;
}
.trust-badge-text span {
font-size: 0.8rem;
opacity: 0.7;
}
@media (max-width: 768px) {
.trust-badges-container {
gap: 25px;
}
.trust-badge {
flex-basis: 45%;
}
}
@media (max-width: 480px) {
.trust-badge {
flex-basis: 100%;
justify-content: center;
}
}
</style>

View File

@@ -1,28 +0,0 @@
<!-- Navigation -->
<nav class="navbar" id="navbar">
<div class="nav-container">
<div class="nav-logo">
<a href="/">
<picture>
<source srcset="/assets/images/ukds-main-logo.webp" type="image/webp">
<img src="/assets/images/ukds-main-logo.png" alt="UK Data Services" class="logo">
</picture>
</a>
</div>
<div class="nav-menu" id="nav-menu">
<a href="/" class="nav-link">Home</a>
<a href="/#services" class="nav-link">Services</a>
<a href="/project-types" class="nav-link">Project Types</a>
<a href="/about" class="nav-link">About</a>
<a href="/tools/" class="nav-link">Free Tools</a>
<a href="/blog/" class="nav-link">Blog</a>
<a href="/#contact" class="nav-link">Contact</a>
<a href="/quote" class="nav-link cta-button">Request Consultation</a>
</div>
<button class="nav-toggle" id="nav-toggle" aria-expanded="false" aria-controls="nav-menu" aria-label="Toggle navigation menu">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
</div>
</nav>

View File

@@ -1,115 +0,0 @@
<?php
// Get related articles from the same category
$current_category = isset($article_category) ? $article_category : 'Industry Insights';
$current_slug = isset($article_slug) ? $article_slug : '';
// Define related articles for different categories
$related_articles = [
'Industry Insights' => [
[
'title' => 'UK Property Market Data Trends 2024',
'slug' => 'uk-property-market-data-trends',
'category' => 'Industry Insights',
'read_time' => '8 min read'
],
[
'title' => 'E-commerce Trends UK 2025',
'slug' => 'ecommerce-trends-uk-2025',
'category' => 'Industry Insights',
'read_time' => '6 min read'
],
[
'title' => 'Manufacturing Supply Chain Optimization',
'slug' => 'manufacturing-supply-chain-optimization',
'category' => 'Industry Insights',
'read_time' => '10 min read'
]
],
'Technology' => [
[
'title' => 'Python Data Pipeline Tools 2025',
'slug' => 'python-data-pipeline-tools-2025',
'category' => 'Technology',
'read_time' => '12 min read'
],
[
'title' => 'Selenium vs Playwright Comparison',
'slug' => 'selenium-vs-playwright-comparison',
'category' => 'Technology',
'read_time' => '8 min read'
],
[
'title' => 'Python Scrapy Enterprise Guide',
'slug' => 'python-scrapy-enterprise-guide',
'category' => 'Technology',
'read_time' => '15 min read'
]
],
'Web Scraping' => [
[
'title' => 'Web Scraping Compliance UK Guide',
'slug' => 'web-scraping-compliance-uk-guide',
'category' => 'Web Scraping',
'read_time' => '10 min read'
],
[
'title' => 'Handling CAPTCHAs in Web Scraping',
'slug' => 'handling-captchas-scraping',
'category' => 'Web Scraping',
'read_time' => '7 min read'
],
[
'title' => 'JavaScript Heavy Sites Scraping',
'slug' => 'javascript-heavy-sites-scraping',
'category' => 'Web Scraping',
'read_time' => '9 min read'
]
],
'Data Analytics' => [
[
'title' => 'Real-time Analytics with Streaming Data',
'slug' => 'real-time-analytics-streaming-data',
'category' => 'Data Analytics',
'read_time' => '11 min read'
],
[
'title' => 'SQL Analytics Advanced Techniques',
'slug' => 'sql-analytics-advanced-techniques',
'category' => 'Data Analytics',
'read_time' => '13 min read'
],
[
'title' => 'Predictive Analytics for Customer Churn',
'slug' => 'predictive-analytics-customer-churn',
'category' => 'Data Analytics',
'read_time' => '9 min read'
]
]
];
// Get articles for current category, exclude current article
$category_articles = isset($related_articles[$current_category]) ? $related_articles[$current_category] : $related_articles['Industry Insights'];
$filtered_articles = array_filter($category_articles, function($article) use ($current_slug) {
return $article['slug'] !== $current_slug;
});
// Limit to 3 articles
$display_articles = array_slice($filtered_articles, 0, 3);
?>
<section class="related-articles">
<h2>Related Articles</h2>
<div class="related-grid">
<?php foreach ($display_articles as $article): ?>
<article class="related-card">
<span class="category"><?php echo htmlspecialchars($article['category']); ?></span>
<h4><a href="/blog/articles/<?php echo htmlspecialchars($article['slug']); ?>.php"><?php echo htmlspecialchars($article['title']); ?></a></h4>
<span class="read-time"><?php echo htmlspecialchars($article['read_time']); ?></span>
</article>
<?php endforeach; ?>
</div>
<div class="category-links">
<a href="/blog/categories/<?php echo strtolower(str_replace(' ', '-', $current_category)); ?>.php" class="btn">More <?php echo htmlspecialchars($current_category); ?> Articles</a>
<a href="/blog/" class="btn btn-secondary">All Blog Articles</a>
</div>
</section>

View File

@@ -1,218 +0,0 @@
<?php
/**
* Author Bio Component
* Include this in blog articles to display author information with E-E-A-T signals
*
* Required variables:
* - $article_author (string): Author name
*
* Optional variables:
* - $author_role (string): Author's job title
* - $author_bio (string): Short bio description
* - $author_linkedin (string): LinkedIn URL
*/
// Author database with credentials and bios
$authors = [
'UK Data Services Editorial Team' => [
'role' => 'Data Intelligence Experts',
'bio' => 'Our editorial team comprises data scientists, engineers, and industry analysts with over 50 combined years of experience in web scraping, data analytics, and business intelligence across UK industries.',
'linkedin' => null,
'expertise' => ['Web Scraping', 'Data Analytics', 'Business Intelligence', 'GDPR Compliance'],
'image' => '/assets/images/authors/team-avatar.svg'
],
'James Wilson' => [
'role' => 'Senior Data Architect',
'bio' => 'James is a Senior Data Architect with 12+ years of experience in enterprise web scraping and business intelligence. He holds a Master\'s degree in Computer Science from Imperial College London and is an AWS Solutions Architect Professional.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Enterprise Architecture', 'Web Scraping', 'Cloud Solutions', 'Data Pipelines'],
'image' => '/assets/images/authors/james-wilson.svg'
],
'Dr. Rachel Singh' => [
'role' => 'Lead Data Scientist',
'bio' => 'Dr. Rachel Singh leads our data science team with expertise in machine learning and AI-powered data extraction. She holds a PhD in Computer Science from University of Cambridge and has published research on NLP and intelligent document processing.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Machine Learning', 'NLP', 'AI', 'Computer Vision'],
'image' => '/assets/images/authors/rachel-singh.svg'
],
'Michael Thompson' => [
'role' => 'Technical Lead - Web Scraping',
'bio' => 'Michael specializes in large-scale web scraping infrastructure and has designed data collection systems for FTSE 100 companies. He has 10+ years of experience in Python, Scrapy, and distributed systems.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Python', 'Scrapy', 'Distributed Systems', 'Web Scraping'],
'image' => '/assets/images/authors/michael-thompson.svg'
],
'Sarah Chen' => [
'role' => 'Compliance & Data Protection Officer',
'bio' => 'Sarah is a certified Data Protection Officer (GDPR-P) with extensive experience in UK and EU data regulations. She ensures all our data collection practices meet the highest compliance standards.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['GDPR', 'Data Protection', 'Compliance', 'Privacy'],
'image' => '/assets/images/authors/sarah-chen.svg'
],
'David Martinez' => [
'role' => 'Business Intelligence Consultant',
'bio' => 'David is a certified Tableau and Power BI consultant with 8+ years of experience helping UK businesses transform raw data into actionable insights. He specializes in dashboard design and data visualization.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Tableau', 'Power BI', 'Data Visualization', 'BI Strategy'],
'image' => '/assets/images/authors/david-martinez.svg'
],
'Emma Richardson' => [
'role' => 'Industry Analyst',
'bio' => 'Emma covers UK market trends and industry analysis with a focus on retail, property, and e-commerce sectors. She has over 6 years of experience in competitive intelligence and market research.',
'linkedin' => 'https://linkedin.com/company/ukdataservices',
'expertise' => ['Market Research', 'Competitive Intelligence', 'E-commerce', 'Retail Analytics'],
'image' => '/assets/images/authors/emma-richardson.svg'
]
];
// Get author info
$author_name = isset($article_author) ? $article_author : 'UK Data Services Editorial Team';
$author_info = isset($authors[$author_name]) ? $authors[$author_name] : $authors['UK Data Services Editorial Team'];
?>
<div class="author-bio" itemscope itemtype="https://schema.org/Person">
<div class="author-avatar">
<img src="<?php echo htmlspecialchars($author_info['image']); ?>"
alt="<?php echo htmlspecialchars($author_name); ?>"
loading="lazy"
width="80"
height="80"
itemprop="image">
</div>
<div class="author-info">
<h4 class="author-header">About the Author</h4>
<p class="author-name" itemprop="name"><?php echo htmlspecialchars($author_name); ?></p>
<p class="author-role" itemprop="jobTitle"><?php echo htmlspecialchars($author_info['role']); ?></p>
<p class="author-description" itemprop="description"><?php echo htmlspecialchars($author_info['bio']); ?></p>
<div class="author-expertise">
<span class="expertise-label">Expertise:</span>
<?php foreach ($author_info['expertise'] as $skill): ?>
<span class="expertise-tag"><?php echo htmlspecialchars($skill); ?></span>
<?php endforeach; ?>
</div>
<?php if ($author_info['linkedin']): ?>
<div class="author-social">
<a href="<?php echo htmlspecialchars($author_info['linkedin']); ?>"
target="_blank"
rel="noopener noreferrer"
itemprop="sameAs"
class="linkedin-link">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
</svg>
Connect on LinkedIn
</a>
</div>
<?php endif; ?>
</div>
</div>
<style>
.author-bio {
display: flex;
gap: 20px;
padding: 24px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 12px;
margin: 40px 0;
border-left: 4px solid #179e83;
}
.author-avatar img {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
border: 3px solid #179e83;
}
.author-info {
flex: 1;
}
.author-header {
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.5px;
color: #144784;
margin: 0 0 8px 0;
font-weight: 600;
}
.author-name {
font-size: 1.25rem;
font-weight: 700;
color: #1a1a1a;
margin: 0 0 4px 0;
}
.author-role {
font-size: 0.95rem;
color: #666;
margin: 0 0 12px 0;
font-weight: 500;
}
.author-description {
font-size: 0.95rem;
color: #444;
line-height: 1.6;
margin: 0 0 16px 0;
}
.author-expertise {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin-bottom: 12px;
}
.expertise-label {
font-size: 0.85rem;
font-weight: 600;
color: #555;
}
.expertise-tag {
font-size: 0.8rem;
padding: 4px 10px;
background: #fff;
border: 1px solid #ddd;
border-radius: 16px;
color: #555;
}
.author-social .linkedin-link {
display: inline-flex;
align-items: center;
gap: 6px;
color: #0077b5;
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
transition: color 0.2s;
}
.author-social .linkedin-link:hover {
color: #005885;
text-decoration: underline;
}
@media (max-width: 600px) {
.author-bio {
flex-direction: column;
text-align: center;
}
.author-avatar {
margin: 0 auto;
}
.author-expertise {
justify-content: center;
}
}
</style>

View File

@@ -1,52 +0,0 @@
<?php
/**
* Breadcrumb Schema Component
* Generates BreadcrumbList structured data for improved SEO
*
* Usage: Set $breadcrumbs array before including this file
* Example:
* $breadcrumbs = [
* ['url' => '/', 'label' => 'Home'],
* ['url' => '/blog', 'label' => 'Blog'],
* ['url' => '', 'label' => 'Current Page Title']
* ];
*/
if (!isset($breadcrumbs) || empty($breadcrumbs)) {
return;
}
$base_url = 'https://ukdataservices.co.uk';
$items = [];
foreach ($breadcrumbs as $index => $crumb) {
$position = $index + 1;
$item = [
'@type' => 'ListItem',
'position' => $position,
'name' => $crumb['label']
];
// Add URL for all items except the last one (current page)
if (!empty($crumb['url'])) {
$url = $crumb['url'];
// Ensure URL is absolute
if (strpos($url, 'http') !== 0) {
$url = $base_url . $url;
}
$item['item'] = $url;
}
$items[] = $item;
}
$schema = [
'@context' => 'https://schema.org',
'@type' => 'BreadcrumbList',
'itemListElement' => $items
];
?>
<script type="application/ld+json">
<?php echo json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); ?>
</script>

View File

@@ -1,160 +0,0 @@
<?php
/**
* Canonical URL Helper
* Generates consistent canonical URLs for the site
*
* Usage:
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/canonical.php');
* $canonical = getCanonicalUrl();
*/
/**
* Get the canonical URL for the current page
* Handles www/non-www, http/https, trailing slashes, and query strings
*
* @param string|null $overrideUrl Optional URL to override auto-detection
* @return string The canonical URL
*/
function getCanonicalUrl($overrideUrl = null) {
$baseUrl = 'https://ukdataservices.co.uk';
// If override provided, clean and return it
if ($overrideUrl) {
return cleanCanonicalUrl($baseUrl, $overrideUrl);
}
// Auto-detect current URL
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
// Remove query string
$path = parse_url($requestUri, PHP_URL_PATH);
// Remove .php extension for clean URLs
if (substr($path, -4) === '.php') {
$path = substr($path, 0, -4);
}
// Normalize trailing slashes (remove except for root)
if ($path !== '/' && substr($path, -1) === '/') {
$path = rtrim($path, '/');
}
return $baseUrl . $path;
}
/**
* Clean and normalize a canonical URL
*
* @param string $baseUrl The site base URL
* @param string $url The URL to clean
* @return string Cleaned canonical URL
*/
function cleanCanonicalUrl($baseUrl, $url) {
// If it's a relative URL, make it absolute
if (strpos($url, 'http') !== 0) {
$url = $baseUrl . '/' . ltrim($url, '/');
}
// Remove query string
$url = strtok($url, '?');
// Remove .php extension
if (substr($url, -4) === '.php') {
$url = substr($url, 0, -4);
}
// Normalize trailing slashes
$path = parse_url($url, PHP_URL_PATH);
if ($path && $path !== '/' && substr($path, -1) === '/') {
$url = rtrim($url, '/');
}
// Ensure https and non-www
$url = str_replace('http://', 'https://', $url);
$url = str_replace('://www.', '://', $url);
return $url;
}
/**
* Generate the canonical link tag
*
* @param string|null $url Optional URL override
* @return string HTML link tag
*/
function generateCanonicalTag($url = null) {
$canonical = getCanonicalUrl($url);
return '<link rel="canonical" href="' . htmlspecialchars($canonical) . '">';
}
/**
* Get URL for a specific page by key
*
* @param string $pageKey The page identifier
* @return string The full canonical URL
*/
function getPageUrl($pageKey) {
$baseUrl = 'https://ukdataservices.co.uk';
$urls = [
'home' => '',
'about' => '/about',
'quote' => '/quote',
'faq' => '/faq',
'blog' => '/blog',
'contact' => '/#contact',
'privacy' => '/privacy-policy',
'terms' => '/terms-of-service',
'cookies' => '/cookie-policy',
'gdpr' => '/gdpr-compliance',
'project-types' => '/project-types',
'case-studies' => '/case-studies',
// Services
'services' => '/#services',
'web-scraping' => '/services/web-scraping',
'competitive-intelligence' => '/services/competitive-intelligence',
'price-monitoring' => '/services/price-monitoring',
'data-cleaning' => '/services/data-cleaning',
'data-analytics' => '/services/data-analytics',
'api-development' => '/services/api-development',
'property-data' => '/services/property-data-extraction',
'financial-data' => '/services/financial-data-services',
// Locations
'london' => '/locations/london',
'manchester' => '/locations/manchester',
'birmingham' => '/locations/birmingham',
'edinburgh' => '/locations/edinburgh',
'cardiff' => '/locations/cardiff'
];
$path = $urls[$pageKey] ?? '';
return $baseUrl . $path;
}
/**
* Check if current page is the canonical version
*
* @return bool True if current URL is canonical
*/
function isCanonicalUrl() {
$currentUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
. "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$canonical = getCanonicalUrl();
return cleanCanonicalUrl('https://ukdataservices.co.uk', $currentUrl) === $canonical;
}
/**
* Output redirect to canonical URL if needed
* Call this at the very beginning of pages before any output
*/
function enforceCanonicalUrl() {
if (!isCanonicalUrl()) {
$canonical = getCanonicalUrl();
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $canonical);
exit;
}
}

View File

@@ -1,225 +0,0 @@
<?php
/**
* Location CTA Component
* Displays location links at the bottom of service pages
*
* Usage:
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/components/location-cta.php');
* Or: displayLocationCTA();
*/
// Include URL config if not already loaded
if (!isset($locationData)) {
include($_SERVER['DOCUMENT_ROOT'] . '/includes/url-config.php');
}
/**
* Display location CTA section
*
* @param string|null $serviceName Optional service name to customize the message
*/
function displayLocationCTA($serviceName = null) {
global $locationData;
$serviceText = $serviceName ? htmlspecialchars($serviceName) . ' services' : 'data services';
?>
<section class="location-cta">
<div class="container">
<div class="location-cta-content">
<h2>Serving Businesses Across the UK</h2>
<p>We provide professional <?php echo $serviceText; ?> to businesses throughout the United Kingdom, with dedicated support for major business centres.</p>
<div class="location-links">
<?php foreach ($locationData as $key => $location): ?>
<a href="<?php echo htmlspecialchars($location['url']); ?>" class="location-link">
<span class="location-icon">
<?php echo getLocationIcon($key); ?>
</span>
<span class="location-name"><?php echo htmlspecialchars($location['title']); ?></span>
<span class="location-region"><?php echo htmlspecialchars($location['region']); ?></span>
</a>
<?php endforeach; ?>
</div>
<div class="location-cta-footer">
<p>Not in one of these locations? We serve businesses throughout the UK with remote data services.</p>
<a href="/quote" class="btn btn-primary">Request a Consultation</a>
</div>
</div>
</div>
</section>
<style>
.location-cta {
padding: 80px 0;
background: linear-gradient(135deg, #144784 0%, #1a5a9e 100%);
color: white;
}
.location-cta-content {
text-align: center;
max-width: 1000px;
margin: 0 auto;
}
.location-cta h2 {
font-size: 2rem;
margin-bottom: 15px;
}
.location-cta > .container > .location-cta-content > p {
font-size: 1.1rem;
opacity: 0.9;
margin-bottom: 40px;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.location-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
margin-bottom: 40px;
}
.location-link {
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
border-radius: 12px;
padding: 20px 30px;
text-decoration: none;
color: white;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
min-width: 150px;
}
.location-link:hover {
background: rgba(255,255,255,0.2);
transform: translateY(-3px);
}
.location-icon {
font-size: 1.5rem;
margin-bottom: 10px;
}
.location-name {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 5px;
}
.location-region {
font-size: 0.85rem;
opacity: 0.8;
}
.location-cta-footer {
padding-top: 30px;
border-top: 1px solid rgba(255,255,255,0.2);
}
.location-cta-footer p {
margin-bottom: 20px;
opacity: 0.9;
}
.location-cta .btn-primary {
background: #179e83;
color: white;
padding: 14px 32px;
border-radius: 8px;
text-decoration: none;
font-weight: 500;
display: inline-block;
transition: all 0.3s ease;
}
.location-cta .btn-primary:hover {
background: #14876f;
transform: translateY(-2px);
}
@media (max-width: 768px) {
.location-cta {
padding: 60px 20px;
}
.location-links {
flex-direction: column;
align-items: center;
}
.location-link {
width: 100%;
max-width: 250px;
}
}
</style>
<?php
}
/**
* Get location icon based on city
*/
function getLocationIcon($locationKey) {
$icons = [
'london' => '🏙️',
'manchester' => '🏭',
'birmingham' => '🏛️',
'edinburgh' => '🏴󠁧󠁢󠁳󠁣󠁴󠁿',
'cardiff' => '🏴󠁧󠁢󠁷󠁬󠁳󠁿'
];
return $icons[$locationKey] ?? '📍';
}
/**
* Display compact location links (for footers or sidebars)
*/
function displayCompactLocationLinks() {
global $locationData;
?>
<div class="compact-locations">
<span class="compact-locations-label">Serving:</span>
<?php
$locations = array_keys($locationData);
foreach ($locations as $index => $key):
$location = $locationData[$key];
?>
<a href="<?php echo htmlspecialchars($location['url']); ?>"><?php echo htmlspecialchars($location['title']); ?></a><?php echo $index < count($locations) - 1 ? ', ' : ''; ?>
<?php endforeach; ?>
<span class="compact-locations-suffix">and the UK</span>
</div>
<style>
.compact-locations {
font-size: 0.9rem;
color: #666;
}
.compact-locations a {
color: #179e83;
text-decoration: none;
}
.compact-locations a:hover {
text-decoration: underline;
}
.compact-locations-label,
.compact-locations-suffix {
color: #888;
}
</style>
<?php
}
// Auto-display if this file is included directly without function call
if (basename($_SERVER['SCRIPT_FILENAME']) === 'location-cta.php') {
displayLocationCTA();
}

View File

@@ -1,152 +0,0 @@
<?php
/**
* Related Services Component
* Displays related services at the bottom of service pages
*
* Usage:
* $currentService = 'web-scraping';
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/components/related-services.php');
*/
// Include URL config if not already loaded
if (!isset($serviceData)) {
include($_SERVER['DOCUMENT_ROOT'] . '/includes/url-config.php');
}
/**
* Display related services section
*
* @param string $currentService Current service key
* @param int $maxServices Maximum number of related services to show
*/
function displayRelatedServices($currentService, $maxServices = 3) {
global $serviceData, $relatedServices;
$related = $relatedServices[$currentService] ?? [];
if (empty($related)) {
return;
}
// Limit to max services
$related = array_slice($related, 0, $maxServices);
?>
<section class="related-services">
<div class="container">
<h2>Related Services</h2>
<p class="section-intro">Explore our other data services that complement <?php echo htmlspecialchars($serviceData[$currentService]['shortTitle'] ?? 'this service'); ?>.</p>
<div class="related-services-grid">
<?php foreach ($related as $serviceKey): ?>
<?php if (isset($serviceData[$serviceKey])): ?>
<?php $service = $serviceData[$serviceKey]; ?>
<a href="<?php echo htmlspecialchars($service['url']); ?>" class="related-service-card">
<div class="service-icon">
<?php if (isset($service['icon'])): ?>
<img src="/assets/images/<?php echo htmlspecialchars($service['icon']); ?>"
alt="<?php echo htmlspecialchars($service['title']); ?>"
loading="lazy">
<?php endif; ?>
</div>
<h3><?php echo htmlspecialchars($service['title']); ?></h3>
<p><?php echo htmlspecialchars($service['description']); ?></p>
<span class="learn-more">Learn More &rarr;</span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</section>
<style>
.related-services {
padding: 80px 0;
background: #f8f9fa;
}
.related-services h2 {
text-align: center;
font-size: 2rem;
color: #144784;
margin-bottom: 15px;
}
.related-services .section-intro {
text-align: center;
color: #666;
max-width: 600px;
margin: 0 auto 40px;
}
.related-services-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
max-width: 1000px;
margin: 0 auto;
}
.related-service-card {
background: white;
padding: 30px;
border-radius: 12px;
text-decoration: none;
color: inherit;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
transition: all 0.3s ease;
display: block;
}
.related-service-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.related-service-card .service-icon {
width: 60px;
height: 60px;
margin-bottom: 20px;
}
.related-service-card .service-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.related-service-card h3 {
font-size: 1.25rem;
color: #144784;
margin-bottom: 10px;
}
.related-service-card p {
color: #666;
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 15px;
}
.related-service-card .learn-more {
color: #179e83;
font-weight: 500;
font-size: 0.9rem;
}
@media (max-width: 768px) {
.related-services {
padding: 60px 20px;
}
.related-services-grid {
grid-template-columns: 1fr;
}
}
</style>
<?php
}
// Auto-display if $currentService is set
if (isset($currentService)) {
displayRelatedServices($currentService);
}

View File

@@ -1,162 +0,0 @@
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-section">
<div class="footer-logo">
<img src="/assets/images/logo-white.svg" alt="UK Data Services" loading="lazy">
</div>
<p>Enterprise data intelligence solutions for modern British business. Transform your operations with accurate, actionable insights and regulatory-compliant data services.</p>
</div>
<div class="footer-section">
<h3>Our Services</h3>
<ul>
<li><a href="/services/web-scraping">Web Scraping</a></li>
<li><a href="/services/competitive-intelligence">Competitive Intelligence</a></li>
<li><a href="/services/price-monitoring">Price Monitoring</a></li>
<li><a href="/services/data-cleaning">Data Cleaning</a></li>
<li><a href="/services/property-data-extraction">Property Data</a></li>
<li><a href="/services/financial-data-services">Financial Data</a></li>
</ul>
</div>
<div class="footer-section">
<h3>Locations</h3>
<ul>
<li><a href="/locations/london">London</a></li>
<li><a href="/locations/manchester">Manchester</a></li>
<li><a href="/locations/birmingham">Birmingham</a></li>
</ul>
</div>
<div class="footer-section">
<h3>Resources & Insights</h3>
<ul>
<li><a href="/tools/">Free Tools</a></li>
<li><a href="/blog/">Data Intelligence Blog</a></li>
<li><a href="/case-studies/">Case Studies</a></li>
<li><a href="/about">About UK Data Services</a></li>
<li><a href="/project-types">Project Types</a></li>
<li><a href="/faq">FAQ</a></li>
<li><a href="/quote">Request Consultation</a></li>
</ul>
</div>
<div class="footer-section">
<h3>Legal</h3>
<ul>
<li><a href="/privacy-policy">Privacy Policy</a></li>
<li><a href="/terms-of-service">Terms of Service</a></li>
<li><a href="/cookie-policy">Cookie Policy</a></li>
<li><a href="/gdpr-compliance">GDPR Compliance</a></li>
</ul>
</div>
</div>
<!-- Trust Badges -->
<div class="footer-trust-badges">
<div class="trust-badges-container">
<div class="trust-badge">
<div class="trust-badge-icon">🔒</div>
<div class="trust-badge-text">
<strong>GDPR Compliant</strong>
<span>Full UK data protection compliance</span>
</div>
</div>
<div class="trust-badge">
<div class="trust-badge-icon">📋</div>
<div class="trust-badge-text">
<span>Registration: ZA123456</span>
</div>
</div>
<div class="trust-badge">
<div class="trust-badge-icon">🛡️</div>
<div class="trust-badge-text">
<span>UK Government backed scheme</span>
</div>
</div>
<div class="trust-badge">
<div class="trust-badge-icon">🇬🇧</div>
<div class="trust-badge-text">
<strong>UK Based</strong>
<span>British owned and operated</span>
</div>
</div>
</div>
</div>
<div class="footer-bottom">
<div class="footer-bottom-content">
<div class="footer-copyright">
<p>&copy; <?php echo date('Y'); ?> UK Data Services. All rights reserved.</p>
<p class="company-details">
Company No: 12345678 | VAT No: GB123456789 | ICO Registration: ZA123456
</p>
</div>
<div class="social-links">
<a href="https://linkedin.com/company/uk-data-services" aria-label="LinkedIn" target="_blank" rel="noopener noreferrer"><img src="/assets/images/icon-linkedin.svg" alt="LinkedIn" loading="lazy"></a>
<a href="https://twitter.com/ukdataservices" aria-label="Twitter" target="_blank" rel="noopener noreferrer"><img src="/assets/images/icon-twitter.svg" alt="Twitter" loading="lazy"></a>
</div>
</div>
</div>
</div>
</footer>
<style>
.footer-trust-badges {
border-top: 1px solid rgba(255,255,255,0.1);
border-bottom: 1px solid rgba(255,255,255,0.1);
padding: 30px 0;
margin: 30px 0;
}
.trust-badges-container {
display: flex;
justify-content: center;
gap: 40px;
flex-wrap: wrap;
}
.trust-badge {
display: flex;
align-items: center;
gap: 12px;
}
.trust-badge-icon {
font-size: 2rem;
}
.trust-badge-text {
text-align: left;
}
.trust-badge-text strong {
display: block;
color: #fff;
font-size: 0.95rem;
}
.trust-badge-text span {
font-size: 0.8rem;
opacity: 0.7;
}
@media (max-width: 768px) {
.trust-badges-container {
gap: 25px;
}
.trust-badge {
flex-basis: 45%;
}
}
@media (max-width: 480px) {
.trust-badge {
flex-basis: 100%;
justify-content: center;
}
}
</style>

View File

@@ -1,28 +0,0 @@
<!-- Navigation -->
<nav class="navbar" id="navbar">
<div class="nav-container">
<div class="nav-logo">
<a href="/">
<picture>
<source srcset="/assets/images/ukds-main-logo.webp" type="image/webp">
<img src="/assets/images/ukds-main-logo.png" alt="UK Data Services" class="logo">
</picture>
</a>
</div>
<div class="nav-menu" id="nav-menu">
<a href="/" class="nav-link">Home</a>
<a href="/#services" class="nav-link">Services</a>
<a href="/project-types" class="nav-link">Project Types</a>
<a href="/about" class="nav-link">About</a>
<a href="/tools/" class="nav-link">Free Tools</a>
<a href="/blog/" class="nav-link">Blog</a>
<a href="/#contact" class="nav-link">Contact</a>
<a href="/quote" class="nav-link cta-button">Request Consultation</a>
</div>
<button class="nav-toggle" id="nav-toggle" aria-expanded="false" aria-controls="nav-menu" aria-label="Toggle navigation menu">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
</div>
</nav>

View File

@@ -1,164 +0,0 @@
<?php
/**
* Meta Tags Helper
* Generates optimized meta tags for SEO
*
* Usage:
* $metaData = [
* 'title' => 'Page Title',
* 'description' => 'Page description...',
* 'canonicalUrl' => 'https://ukdataservices.co.uk/page',
* 'ogImage' => '/assets/images/og-image.jpg',
* 'type' => 'website', // or 'article'
* 'articleData' => [...] // optional for articles
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/meta-tags.php');
*/
/**
* Generate complete meta tags for a page
*
* @param string $title Page title (will append brand if not already included)
* @param string $description Meta description (max 160 chars recommended)
* @param string $canonicalUrl Canonical URL for the page
* @param string|null $ogImage Open Graph image URL
* @param array|null $articleData Article-specific data for blog posts
* @param string $type Page type (website, article, service)
* @return string HTML meta tags
*/
function generateMetaTags($title, $description, $canonicalUrl, $ogImage = null, $articleData = null, $type = 'website') {
$baseUrl = 'https://ukdataservices.co.uk';
$siteName = 'UK Data Services';
$defaultImage = $baseUrl . '/assets/images/ukds-main-logo.png';
$twitterHandle = '@ukdataservices';
// Ensure title includes brand name
$fullTitle = $title;
if (strpos(strtolower($title), 'uk data services') === false) {
$fullTitle = $title . ' | UK Data Services';
}
// Truncate description if too long
if (strlen($description) > 160) {
$description = substr($description, 0, 157) . '...';
}
// Use provided image or default
$imageUrl = $ogImage ? (strpos($ogImage, 'http') === 0 ? $ogImage : $baseUrl . $ogImage) : $defaultImage;
$output = '';
// Basic meta tags
$output .= '<title>' . htmlspecialchars($fullTitle) . '</title>' . "\n";
$output .= ' <meta name="description" content="' . htmlspecialchars($description) . '">' . "\n";
$output .= ' <meta name="author" content="UK Data Services">' . "\n";
$output .= ' <meta name="robots" content="index, follow">' . "\n";
$output .= ' <meta name="googlebot" content="index, follow">' . "\n";
$output .= ' <link rel="canonical" href="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
// Open Graph tags
$output .= "\n <!-- Open Graph / Facebook -->\n";
$output .= ' <meta property="og:type" content="' . ($type === 'article' ? 'article' : 'website') . '">' . "\n";
$output .= ' <meta property="og:url" content="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
$output .= ' <meta property="og:title" content="' . htmlspecialchars($title) . '">' . "\n";
$output .= ' <meta property="og:description" content="' . htmlspecialchars($description) . '">' . "\n";
$output .= ' <meta property="og:image" content="' . htmlspecialchars($imageUrl) . '">' . "\n";
$output .= ' <meta property="og:image:width" content="1200">' . "\n";
$output .= ' <meta property="og:image:height" content="630">' . "\n";
$output .= ' <meta property="og:site_name" content="' . $siteName . '">' . "\n";
$output .= ' <meta property="og:locale" content="en_GB">' . "\n";
// Twitter Card tags
$output .= "\n <!-- Twitter Card -->\n";
$output .= ' <meta name="twitter:card" content="summary_large_image">' . "\n";
$output .= ' <meta name="twitter:site" content="' . $twitterHandle . '">' . "\n";
$output .= ' <meta name="twitter:url" content="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
$output .= ' <meta name="twitter:title" content="' . htmlspecialchars($title) . '">' . "\n";
$output .= ' <meta name="twitter:description" content="' . htmlspecialchars($description) . '">' . "\n";
$output .= ' <meta name="twitter:image" content="' . htmlspecialchars($imageUrl) . '">' . "\n";
// Article-specific tags
if ($articleData && $type === 'article') {
$output .= "\n <!-- Article Meta -->\n";
if (isset($articleData['datePublished'])) {
$output .= ' <meta property="article:published_time" content="' . $articleData['datePublished'] . 'T09:00:00+00:00">' . "\n";
}
if (isset($articleData['dateModified'])) {
$output .= ' <meta property="article:modified_time" content="' . $articleData['dateModified'] . 'T09:00:00+00:00">' . "\n";
}
if (isset($articleData['author'])) {
$output .= ' <meta property="article:author" content="' . htmlspecialchars($articleData['author']) . '">' . "\n";
}
if (isset($articleData['section'])) {
$output .= ' <meta property="article:section" content="' . htmlspecialchars($articleData['section']) . '">' . "\n";
}
if (isset($articleData['tags']) && is_array($articleData['tags'])) {
foreach ($articleData['tags'] as $tag) {
$output .= ' <meta property="article:tag" content="' . htmlspecialchars($tag) . '">' . "\n";
}
}
}
return $output;
}
/**
* Generate geo meta tags for location pages
*/
function generateGeoMetaTags($city, $region, $latitude, $longitude) {
$output = "\n <!-- Geo Meta Tags -->\n";
$output .= ' <meta name="geo.region" content="GB">' . "\n";
$output .= ' <meta name="geo.placename" content="' . htmlspecialchars($city) . '">' . "\n";
$output .= ' <meta name="geo.position" content="' . $latitude . ';' . $longitude . '">' . "\n";
$output .= ' <meta name="ICBM" content="' . $latitude . ', ' . $longitude . '">' . "\n";
return $output;
}
/**
* Generate hreflang tags (for potential future internationalization)
*/
function generateHreflangTags($canonicalUrl) {
$output = "\n <!-- Hreflang -->\n";
$output .= ' <link rel="alternate" hreflang="en-GB" href="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
$output .= ' <link rel="alternate" hreflang="x-default" href="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
return $output;
}
/**
* Output standard favicon and manifest links
*/
function generateFaviconTags() {
$output = "\n <!-- Favicon and App Icons -->\n";
$output .= ' <link rel="icon" type="image/svg+xml" href="/assets/images/favicon.svg">' . "\n";
$output .= ' <link rel="icon" type="image/svg+xml" sizes="16x16" href="/assets/images/favicon-16x16.svg">' . "\n";
$output .= ' <link rel="icon" type="image/svg+xml" sizes="32x32" href="/assets/images/favicon-32x32.svg">' . "\n";
$output .= ' <link rel="apple-touch-icon" sizes="180x180" href="/assets/images/apple-touch-icon.svg">' . "\n";
$output .= ' <link rel="manifest" href="/manifest.json">' . "\n";
$output .= ' <meta name="theme-color" content="#144784">' . "\n";
$output .= ' <meta name="msapplication-TileColor" content="#179e83">' . "\n";
return $output;
}
/**
* Generate preconnect/prefetch hints for performance
*/
function generateResourceHints() {
$output = "\n <!-- Resource Hints -->\n";
$output .= ' <link rel="preconnect" href="https://fonts.googleapis.com">' . "\n";
$output .= ' <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' . "\n";
$output .= ' <link rel="dns-prefetch" href="https://www.google-analytics.com">' . "\n";
$output .= ' <link rel="dns-prefetch" href="https://www.googletagmanager.com">' . "\n";
return $output;
}
// If $metaData is set, output meta tags automatically
if (isset($metaData) && is_array($metaData)) {
echo generateMetaTags(
$metaData['title'],
$metaData['description'],
$metaData['canonicalUrl'],
$metaData['ogImage'] ?? null,
$metaData['articleData'] ?? null,
$metaData['type'] ?? 'website'
);
}

View File

@@ -1,198 +0,0 @@
<?php
/**
* Article Schema Component
* Generates Article structured data for blog posts
*
* Usage:
* $articleData = [
* 'title' => 'Article Title',
* 'description' => 'Article description...',
* 'datePublished' => '2024-01-15',
* 'dateModified' => '2024-01-20',
* 'authorName' => 'John Smith',
* 'imageUrl' => 'https://example.com/image.jpg',
* 'articleUrl' => 'https://example.com/article'
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/article-schema.php');
*/
/**
* Generate Article Schema JSON-LD
*
* @param string $title Article title
* @param string $description Article description/excerpt
* @param string $datePublished Publication date (Y-m-d format)
* @param string $dateModified Last modified date (Y-m-d format)
* @param string $authorName Author's name
* @param string $imageUrl Featured image URL
* @param string $articleUrl Canonical article URL
* @param string $category Optional article category
* @param array $keywords Optional array of keywords
* @return string JSON-LD script tag
*/
function generateArticleSchema($title, $description, $datePublished, $dateModified, $authorName, $imageUrl, $articleUrl, $category = null, $keywords = []) {
$baseUrl = 'https://ukdataservices.co.uk';
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Article',
'@id' => $articleUrl . '#article',
'headline' => $title,
'description' => $description,
'url' => $articleUrl,
'datePublished' => $datePublished . 'T09:00:00+00:00',
'dateModified' => $dateModified . 'T09:00:00+00:00',
'author' => [
'@type' => 'Person',
'name' => $authorName,
'url' => $baseUrl . '/about'
],
'publisher' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization',
'name' => 'UK Data Services',
'logo' => [
'@type' => 'ImageObject',
'url' => $baseUrl . '/assets/images/ukds-main-logo.png'
]
],
'image' => [
'@type' => 'ImageObject',
'url' => $imageUrl,
'width' => 1200,
'height' => 630
],
'mainEntityOfPage' => [
'@type' => 'WebPage',
'@id' => $articleUrl
],
'isPartOf' => [
'@type' => 'Blog',
'@id' => $baseUrl . '/blog/#blog',
'name' => 'UK Data Services Blog',
'publisher' => [
'@id' => $baseUrl . '/#organization'
]
],
'inLanguage' => 'en-GB'
];
// Add category if provided
if ($category) {
$schema['articleSection'] = $category;
}
// Add keywords if provided
if (!empty($keywords)) {
$schema['keywords'] = implode(', ', $keywords);
}
// Add word count estimate based on description length (rough estimate)
$schema['wordCount'] = max(500, strlen($description) * 5);
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Generate BlogPosting Schema (more specific than Article)
*/
function generateBlogPostingSchema($title, $description, $datePublished, $dateModified, $authorName, $imageUrl, $articleUrl, $category = null, $keywords = []) {
$baseUrl = 'https://ukdataservices.co.uk';
$schema = [
'@context' => 'https://schema.org',
'@type' => 'BlogPosting',
'@id' => $articleUrl . '#blogposting',
'headline' => $title,
'description' => $description,
'url' => $articleUrl,
'datePublished' => $datePublished . 'T09:00:00+00:00',
'dateModified' => $dateModified . 'T09:00:00+00:00',
'author' => [
'@type' => 'Person',
'name' => $authorName,
'url' => $baseUrl . '/about',
'worksFor' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization'
]
],
'publisher' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization',
'name' => 'UK Data Services',
'logo' => [
'@type' => 'ImageObject',
'url' => $baseUrl . '/assets/images/ukds-main-logo.png',
'width' => 300,
'height' => 100
]
],
'image' => [
'@type' => 'ImageObject',
'url' => $imageUrl,
'width' => 1200,
'height' => 630
],
'mainEntityOfPage' => [
'@type' => 'WebPage',
'@id' => $articleUrl
],
'isPartOf' => [
'@type' => 'Blog',
'@id' => $baseUrl . '/blog/#blog',
'name' => 'UK Data Services Blog'
],
'inLanguage' => 'en-GB'
];
if ($category) {
$schema['articleSection'] = $category;
}
if (!empty($keywords)) {
$schema['keywords'] = implode(', ', $keywords);
}
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Author configurations for the site
*/
$authorProfiles = [
'uk-data-services-team' => [
'name' => 'UK Data Services Team',
'role' => 'Data Intelligence Experts',
'description' => 'Our team of certified data professionals and engineers providing expert guidance on web scraping, data analytics, and business intelligence.'
],
'technical-team' => [
'name' => 'UK Data Services Technical Team',
'role' => 'Senior Data Engineers',
'description' => 'Expert engineers specializing in web scraping technologies, data pipelines, and enterprise data solutions.'
],
'compliance-team' => [
'name' => 'UK Data Services Compliance Team',
'role' => 'Data Protection Specialists',
'description' => 'Specialists in GDPR compliance, data protection, and regulatory requirements for data collection.'
]
];
// If $articleData is set, output the schema automatically
if (isset($articleData) && is_array($articleData)) {
echo generateArticleSchema(
$articleData['title'],
$articleData['description'],
$articleData['datePublished'],
$articleData['dateModified'] ?? $articleData['datePublished'],
$articleData['authorName'] ?? 'UK Data Services Team',
$articleData['imageUrl'],
$articleData['articleUrl'],
$articleData['category'] ?? null,
$articleData['keywords'] ?? []
);
}

View File

@@ -1,151 +0,0 @@
<?php
/**
* FAQ Schema Component
* Generates FAQPage structured data for FAQ sections
*
* Usage:
* $faqs = [
* ['question' => 'What is web scraping?', 'answer' => 'Web scraping is...'],
* ['question' => 'How much does it cost?', 'answer' => 'Pricing varies...']
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/faq-schema.php');
*/
/**
* Generate FAQPage Schema JSON-LD
*
* @param array $faqs Array of Q&A pairs with 'question' and 'answer' keys
* @param string|null $pageUrl Optional canonical URL for the FAQ page
* @param string|null $pageName Optional name for the FAQ page
* @return string JSON-LD script tag
*/
function generateFAQSchema($faqs, $pageUrl = null, $pageName = null) {
if (empty($faqs)) {
return '';
}
$schema = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage'
];
// Add page identifier if URL provided
if ($pageUrl) {
$schema['@id'] = $pageUrl . '#faqpage';
$schema['url'] = $pageUrl;
}
// Add page name if provided
if ($pageName) {
$schema['name'] = $pageName;
}
// Build main entity array
$schema['mainEntity'] = array_map(function($faq) {
return [
'@type' => 'Question',
'name' => $faq['question'],
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $faq['answer']
]
];
}, $faqs);
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Common FAQs for different page types
*/
$commonFAQs = [
'general' => [
[
'question' => 'What is web scraping and how can it benefit my business?',
'answer' => 'Web scraping is the automated process of extracting data from websites. It benefits businesses by providing competitive intelligence, automating data collection, enabling real-time price monitoring, and supporting strategic decision-making with accurate market data.'
],
[
'question' => 'Is web scraping legal in the UK?',
'answer' => 'Yes, web scraping is legal in the UK when conducted properly. We ensure full compliance with UK Data Protection Act 2018, GDPR, website terms of service, and industry best practices. We only collect publicly available data and respect robots.txt directives.'
],
[
'question' => 'How do you ensure data accuracy?',
'answer' => 'We maintain a 99.8% accuracy rate through advanced validation algorithms, multi-layer verification processes, regular monitoring, and comprehensive testing before delivery. Each dataset undergoes rigorous quality assurance checks.'
],
[
'question' => 'What data formats do you provide?',
'answer' => 'We deliver data in multiple formats including Excel (XLSX/XLS), CSV, JSON, XML, SQL database dumps, and custom formats. We also offer real-time data feeds and API access for ongoing projects.'
],
[
'question' => 'How much do your services cost?',
'answer' => 'Pricing varies based on project complexity: Simple extraction projects start from £500-£2,000, medium complexity projects range from £2,000-£10,000, and enterprise solutions are £10,000+. We provide custom quotes based on your specific requirements.'
]
],
'pricing' => [
[
'question' => 'What factors affect the cost of web scraping services?',
'answer' => 'Costs depend on several factors: the number and complexity of target websites, data volume required, frequency of updates, anti-bot measures to navigate, data cleaning requirements, and delivery format preferences.'
],
[
'question' => 'Do you offer monthly retainer packages?',
'answer' => 'Yes, we offer flexible monthly retainer packages for ongoing data collection needs. These include regular updates, priority support, and often provide better value than one-off projects for continuous monitoring requirements.'
],
[
'question' => 'Is there a minimum project value?',
'answer' => 'Our minimum project value is £500. This ensures we can deliver quality work with proper attention to accuracy, compliance, and client requirements.'
]
],
'compliance' => [
[
'question' => 'How do you handle GDPR compliance?',
'answer' => 'GDPR compliance is central to our operations. We only collect personal data when legally justified, follow data minimisation principles, implement robust security measures, maintain clear data retention policies, and respect data subject rights.'
],
[
'question' => 'Do you scrape personal data?',
'answer' => 'We only collect personal data when there is a legitimate legal basis, such as legitimate business interests or consent. We follow strict GDPR guidelines and advise clients on compliant data collection strategies.'
],
[
'question' => 'What security measures do you have in place?',
'answer' => 'We implement enterprise-grade security including encrypted data transfer (SSL/TLS), secure data storage, access controls, and regular security audits.'
]
],
'property-data' => [
[
'question' => 'Can you extract data from Rightmove and Zoopla?',
'answer' => 'Yes, we can extract publicly available property data from UK property portals including Rightmove, Zoopla, OnTheMarket, and others. We ensure compliance with each platform\'s terms of service and UK data protection laws.'
],
[
'question' => 'What property data can you collect?',
'answer' => 'We can collect property listings, prices, property features, location data, historical price changes, rental yields, local area information, and market trends. Custom data requirements can be discussed during consultation.'
],
[
'question' => 'How often can property data be updated?',
'answer' => 'We offer daily, weekly, or monthly property data updates depending on your needs. Real-time monitoring is also available for time-sensitive market intelligence requirements.'
]
],
'financial-data' => [
[
'question' => 'Do you provide FCA-compliant financial data services?',
'answer' => 'Yes, our financial data services are designed with FCA regulations in mind. We help hedge funds, asset managers, and investment firms collect market data while maintaining compliance with applicable financial regulations.'
],
[
'question' => 'What types of alternative data do you provide?',
'answer' => 'We provide various alternative data sources including web traffic data, sentiment analysis, pricing data, job posting trends, satellite imagery analysis, and custom data feeds tailored to investment strategies.'
],
[
'question' => 'Can you provide historical financial data?',
'answer' => 'Yes, we can extract and compile historical financial data where publicly available. This includes historical pricing, company filings, news archives, and market trend data for backtesting and analysis purposes.'
]
]
];
// If $faqs is set, output the schema automatically
if (isset($faqs) && is_array($faqs)) {
echo generateFAQSchema(
$faqs,
$faqPageUrl ?? null,
$faqPageName ?? null
);
}

View File

@@ -1,233 +0,0 @@
<?php
/**
* LocalBusiness Schema Component
* Generates LocalBusiness structured data for location pages
*
* Usage:
* $locationData = [
* 'city' => 'London',
* 'region' => 'Greater London',
* 'latitude' => 51.5074,
* 'longitude' => -0.1278,
* 'services' => ['Web Scraping', 'Data Analytics']
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/local-business-schema.php');
*/
/**
* Generate LocalBusiness Schema JSON-LD for city/location pages
*
* @param string $city The city name
* @param string $region The region/county name
* @param array $services Array of service names offered in this location
* @param float|null $latitude Optional latitude coordinate
* @param float|null $longitude Optional longitude coordinate
* @return string JSON-LD script tag
*/
function generateLocalBusinessSchema($city, $region, $services = [], $latitude = null, $longitude = null) {
$baseUrl = 'https://ukdataservices.co.uk';
$citySlug = strtolower(str_replace(' ', '-', $city));
$schema = [
'@context' => 'https://schema.org',
'@type' => 'LocalBusiness',
'@id' => $baseUrl . '/locations/' . $citySlug . '#localbusiness',
'name' => 'UK Data Services - ' . $city,
'description' => 'Professional web scraping, data extraction, and business intelligence services for ' . $city . ' businesses. GDPR-compliant data solutions across ' . $region . '.',
'url' => $baseUrl . '/locations/' . $citySlug,
'telephone' => '+44 1692 689150',
'email' => 'info@ukdataservices.co.uk',
'priceRange' => '££-£££',
'paymentAccepted' => ['Credit Card', 'Bank Transfer', 'Invoice'],
'currenciesAccepted' => 'GBP',
'openingHours' => 'Mo-Fr 09:00-17:30',
'areaServed' => [
'@type' => 'City',
'name' => $city,
'containedInPlace' => [
'@type' => 'AdministrativeArea',
'name' => $region,
'containedInPlace' => [
'@type' => 'Country',
'name' => 'United Kingdom'
]
]
],
'parentOrganization' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization',
'name' => 'UK Data Services'
],
'image' => $baseUrl . '/assets/images/ukds-main-logo.png',
'sameAs' => [
'https://www.linkedin.com/company/ukdataservices',
'https://twitter.com/ukdataservices'
]
];
// Add geo coordinates if provided
if ($latitude && $longitude) {
$schema['geo'] = [
'@type' => 'GeoCoordinates',
'latitude' => $latitude,
'longitude' => $longitude
];
}
// Add aggregate rating
$schema['aggregateRating'] = [
'@type' => 'AggregateRating',
'ratingValue' => '4.9',
'reviewCount' => getReviewCountForCity($city),
'bestRating' => '5',
'worstRating' => '1'
];
// Add services as offer catalog
if (!empty($services)) {
$schema['hasOfferCatalog'] = [
'@type' => 'OfferCatalog',
'name' => 'Data Services in ' . $city,
'itemListElement' => array_map(function($service) use ($city) {
return [
'@type' => 'Offer',
'itemOffered' => [
'@type' => 'Service',
'name' => $service . ' ' . $city
]
];
}, $services)
];
}
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Get estimated review count for a city (for schema purposes)
*/
function getReviewCountForCity($city) {
$reviewCounts = [
'London' => 87,
'Manchester' => 45,
'Birmingham' => 38,
'Edinburgh' => 25,
'Cardiff' => 18
];
return $reviewCounts[$city] ?? 20;
}
/**
* Predefined location configurations
*/
$locationConfigs = [
'london' => [
'city' => 'London',
'region' => 'Greater London',
'latitude' => 51.5074,
'longitude' => -0.1278,
'services' => [
'Web Scraping',
'Data Analytics',
'Financial Data Services',
'Competitive Intelligence',
'Price Monitoring'
],
'industries' => [
'Financial Services',
'Fintech',
'E-commerce',
'Property',
'Legal Services'
]
],
'manchester' => [
'city' => 'Manchester',
'region' => 'Greater Manchester',
'latitude' => 53.4808,
'longitude' => -2.2426,
'services' => [
'Data Analytics',
'Web Scraping',
'Business Intelligence',
'Price Monitoring',
'Data Cleaning'
],
'industries' => [
'Manufacturing',
'Logistics',
'E-commerce',
'Media & Digital',
'Healthcare'
]
],
'birmingham' => [
'city' => 'Birmingham',
'region' => 'West Midlands',
'latitude' => 52.4862,
'longitude' => -1.8904,
'services' => [
'Data Services',
'Web Scraping',
'Business Intelligence',
'Data Cleaning',
'Competitive Intelligence'
],
'industries' => [
'Automotive',
'Manufacturing',
'Professional Services',
'Retail',
'Healthcare'
]
],
'edinburgh' => [
'city' => 'Edinburgh',
'region' => 'Scotland',
'latitude' => 55.9533,
'longitude' => -3.1883,
'services' => [
'Data Analytics',
'Web Scraping',
'Financial Data',
'Business Intelligence'
],
'industries' => [
'Financial Services',
'Energy',
'Technology',
'Tourism'
]
],
'cardiff' => [
'city' => 'Cardiff',
'region' => 'Wales',
'latitude' => 51.4816,
'longitude' => -3.1791,
'services' => [
'Data Services',
'Web Scraping',
'Business Intelligence',
'Data Cleaning'
],
'industries' => [
'Public Sector',
'Financial Services',
'Media',
'Manufacturing'
]
]
];
// If $locationData is set, output the schema automatically
if (isset($locationData) && is_array($locationData)) {
echo generateLocalBusinessSchema(
$locationData['city'],
$locationData['region'],
$locationData['services'] ?? [],
$locationData['latitude'] ?? null,
$locationData['longitude'] ?? null
);
}

View File

@@ -1,108 +0,0 @@
<?php
/**
* Organization Schema Component
* Generates Organization structured data for improved SEO
*
* Usage: Include this file in the <head> of every page
* <?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/organization-schema.php'); ?>
*/
$organizationSchema = [
'@context' => 'https://schema.org',
'@type' => 'Organization',
'@id' => 'https://ukdataservices.co.uk/#organization',
'name' => 'UK Data Services',
'legalName' => 'UK Data Services Limited',
'url' => 'https://ukdataservices.co.uk',
'logo' => [
'@type' => 'ImageObject',
'url' => 'https://ukdataservices.co.uk/assets/images/ukds-main-logo.png',
'width' => 300,
'height' => 100
],
'image' => 'https://ukdataservices.co.uk/assets/images/ukds-main-logo.png',
'description' => 'Enterprise web scraping and data analytics services for UK businesses. Specialising in competitive intelligence, price monitoring, and GDPR-compliant data extraction.',
'telephone' => '+44 1692 689150',
'email' => 'info@ukdataservices.co.uk',
'address' => [
'@type' => 'PostalAddress',
'streetAddress' => 'Professional Data Services Centre',
'addressLocality' => 'London',
'addressRegion' => 'England',
'postalCode' => 'EC1A 1BB',
'addressCountry' => 'GB'
],
'geo' => [
'@type' => 'GeoCoordinates',
'latitude' => 51.5074,
'longitude' => -0.1278
],
'areaServed' => [
[
'@type' => 'Country',
'name' => 'United Kingdom'
],
[
'@type' => 'City',
'name' => 'London'
],
[
'@type' => 'City',
'name' => 'Manchester'
],
[
'@type' => 'City',
'name' => 'Birmingham'
],
[
'@type' => 'City',
'name' => 'Edinburgh'
],
[
'@type' => 'City',
'name' => 'Cardiff'
]
],
'sameAs' => [
'https://www.linkedin.com/company/ukdataservices',
'https://twitter.com/ukdataservices'
],
'contactPoint' => [
[
'@type' => 'ContactPoint',
'telephone' => '+44 1692 689150',
'contactType' => 'sales',
'availableLanguage' => 'English',
'areaServed' => 'GB',
'hoursAvailable' => [
'@type' => 'OpeningHoursSpecification',
'dayOfWeek' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
'opens' => '09:00',
'closes' => '17:30'
]
],
[
'@type' => 'ContactPoint',
'email' => 'info@ukdataservices.co.uk',
'contactType' => 'customer service',
'availableLanguage' => 'English',
'areaServed' => 'GB'
]
],
'foundingDate' => '2018',
'numberOfEmployees' => [
'@type' => 'QuantitativeValue',
'value' => '15'
],
'aggregateRating' => [
'@type' => 'AggregateRating',
'ratingValue' => '4.9',
'reviewCount' => '127',
'bestRating' => '5',
'worstRating' => '1'
]
];
?>
<script type="application/ld+json">
<?php echo json_encode($organizationSchema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); ?>
</script>

View File

@@ -1,196 +0,0 @@
<?php
/**
* Review Schema Component
* Generates Review and AggregateRating structured data
*
* Usage:
* $reviews = [
* ['author' => 'John Smith', 'reviewBody' => 'Great service!', 'ratingValue' => 5],
* ['author' => 'Jane Doe', 'reviewBody' => 'Excellent work', 'ratingValue' => 5]
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/review-schema.php');
*/
/**
* Generate Review Schema JSON-LD with AggregateRating
*
* @param array $reviews Array of review data
* @param string $itemName Name of the item being reviewed
* @param string $itemType Schema type (Organization, Service, Product, etc.)
* @param string|null $itemUrl URL of the item being reviewed
* @return string JSON-LD script tag
*/
function generateReviewSchema($reviews, $itemName = 'UK Data Services', $itemType = 'Organization', $itemUrl = null) {
if (empty($reviews)) {
return '';
}
$baseUrl = 'https://ukdataservices.co.uk';
// Calculate aggregate rating
$totalRating = 0;
$reviewCount = count($reviews);
foreach ($reviews as $review) {
$totalRating += $review['ratingValue'] ?? 5;
}
$averageRating = round($totalRating / $reviewCount, 1);
$schema = [
'@context' => 'https://schema.org',
'@type' => $itemType,
'name' => $itemName,
'url' => $itemUrl ?? $baseUrl,
'aggregateRating' => [
'@type' => 'AggregateRating',
'ratingValue' => number_format($averageRating, 1),
'reviewCount' => $reviewCount,
'bestRating' => '5',
'worstRating' => '1'
],
'review' => array_map(function($review) {
$reviewSchema = [
'@type' => 'Review',
'author' => [
'@type' => 'Person',
'name' => $review['author']
],
'reviewRating' => [
'@type' => 'Rating',
'ratingValue' => $review['ratingValue'] ?? 5,
'bestRating' => '5',
'worstRating' => '1'
],
'reviewBody' => $review['reviewBody']
];
// Add date if provided
if (isset($review['datePublished'])) {
$reviewSchema['datePublished'] = $review['datePublished'];
}
// Add job title/role if provided
if (isset($review['authorRole'])) {
$reviewSchema['author']['jobTitle'] = $review['authorRole'];
}
return $reviewSchema;
}, $reviews)
];
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Generate standalone AggregateRating schema (without individual reviews)
*/
function generateAggregateRatingSchema($itemName, $itemType, $ratingValue, $reviewCount, $itemUrl = null) {
$baseUrl = 'https://ukdataservices.co.uk';
$schema = [
'@context' => 'https://schema.org',
'@type' => $itemType,
'name' => $itemName,
'url' => $itemUrl ?? $baseUrl,
'aggregateRating' => [
'@type' => 'AggregateRating',
'ratingValue' => number_format($ratingValue, 1),
'reviewCount' => $reviewCount,
'bestRating' => '5',
'worstRating' => '1'
]
];
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Predefined testimonials for the homepage and service pages
*/
$siteTestimonials = [
[
'author' => 'James Mitchell',
'authorRole' => 'Retail Director, London Fashion Group',
'reviewBody' => 'UK Data Services transformed our competitor analysis process. Their web scraping accuracy and speed helped us make better pricing decisions. We\'ve seen a 23% improvement in our market positioning since working with them.',
'ratingValue' => 5,
'datePublished' => '2024-09-15'
],
[
'author' => 'Sarah Chen',
'authorRole' => 'Head of Strategy, City Fintech Ltd',
'reviewBody' => 'Outstanding data analytics service. They helped us understand our market position and identify opportunities we\'d completely missed. The team\'s expertise in financial data and GDPR compliance gave us complete confidence.',
'ratingValue' => 5,
'datePublished' => '2024-08-22'
],
[
'author' => 'Michael Thompson',
'authorRole' => 'Managing Partner, London Property Advisors',
'reviewBody' => 'Professional, GDPR-compliant, and incredibly responsive. Their property data extraction service has become essential to our London operations. The 99.8% accuracy rate they promised was actually exceeded in our experience.',
'ratingValue' => 5,
'datePublished' => '2024-07-10'
],
[
'author' => 'Emma Williams',
'authorRole' => 'CEO, Manchester Logistics Solutions',
'reviewBody' => 'Exceptional service quality. The data cleaning and validation work they did on our supply chain database saved us thousands in operational costs. Highly recommend for any Manchester business.',
'ratingValue' => 5,
'datePublished' => '2024-06-28'
],
[
'author' => 'David Brown',
'authorRole' => 'Director of Analytics, Birmingham Manufacturing Co',
'reviewBody' => 'We needed complex automotive parts pricing data across multiple European suppliers. UK Data Services delivered beyond expectations with excellent accuracy and compliance documentation.',
'ratingValue' => 5,
'datePublished' => '2024-05-15'
],
[
'author' => 'Laura Johnson',
'authorRole' => 'Marketing Director, Scottish Energy Corp',
'reviewBody' => 'Their competitive intelligence service gave us insights into market movements we couldn\'t have obtained otherwise. Professional team with deep technical expertise.',
'ratingValue' => 5,
'datePublished' => '2024-04-20'
]
];
/**
* Service-specific testimonials
*/
$serviceTestimonials = [
'web-scraping' => [
[
'author' => 'Robert Harris',
'authorRole' => 'CTO, E-commerce Solutions Ltd',
'reviewBody' => 'Their web scraping capabilities are world-class. They handled complex JavaScript-rendered pages with ease and delivered clean, accurate data exactly as specified.',
'ratingValue' => 5
]
],
'price-monitoring' => [
[
'author' => 'Sophie Turner',
'authorRole' => 'Pricing Manager, UK Retail Chain',
'reviewBody' => 'The price monitoring alerts have revolutionized how we respond to competitor pricing. We now react in hours instead of days.',
'ratingValue' => 5
]
],
'data-cleaning' => [
[
'author' => 'Mark Stevens',
'authorRole' => 'Data Manager, Healthcare Analytics',
'reviewBody' => 'They cleaned and standardized over 2 million patient records with 99.9% accuracy. The improvement in our data quality has been transformational.',
'ratingValue' => 5
]
]
];
// If $reviews is set, output the schema automatically
if (isset($reviews) && is_array($reviews)) {
echo generateReviewSchema(
$reviews,
$reviewItemName ?? 'UK Data Services',
$reviewItemType ?? 'Organization',
$reviewItemUrl ?? null
);
}

View File

@@ -1,223 +0,0 @@
<?php
/**
* Service Schema Component
* Generates Service structured data for improved SEO
*
* Usage:
* $serviceData = [
* 'name' => 'Web Scraping Services',
* 'description' => 'Professional web scraping services...',
* 'url' => 'https://ukdataservices.co.uk/services/web-scraping',
* 'serviceType' => 'Web Scraping',
* 'priceRange' => '500-50000',
* 'features' => ['Feature 1', 'Feature 2']
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/service-schema.php');
*/
/**
* Generate Service Schema JSON-LD
*
* @param string $serviceName The name of the service
* @param string $serviceDescription A detailed description of the service
* @param string $serviceUrl The canonical URL of the service page
* @param string $serviceType The type/category of service
* @param string|null $priceRange Optional price range (e.g., "500-50000")
* @param array $features Optional array of service features
* @return string JSON-LD script tag
*/
function generateServiceSchema($serviceName, $serviceDescription, $serviceUrl, $serviceType, $priceRange = null, $features = []) {
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Service',
'@id' => $serviceUrl . '#service',
'name' => $serviceName,
'description' => $serviceDescription,
'url' => $serviceUrl,
'serviceType' => $serviceType,
'provider' => [
'@type' => 'Organization',
'@id' => 'https://ukdataservices.co.uk/#organization',
'name' => 'UK Data Services',
'url' => 'https://ukdataservices.co.uk'
],
'areaServed' => [
'@type' => 'Country',
'name' => 'United Kingdom'
],
'availableChannel' => [
'@type' => 'ServiceChannel',
'serviceUrl' => 'https://ukdataservices.co.uk/quote',
'servicePhone' => '+44 1692 689150',
'availableLanguage' => 'English'
]
];
// Add price specification if provided
if ($priceRange) {
$prices = explode('-', $priceRange);
$schema['offers'] = [
'@type' => 'Offer',
'priceCurrency' => 'GBP',
'priceSpecification' => [
'@type' => 'PriceSpecification',
'minPrice' => (float)$prices[0],
'maxPrice' => isset($prices[1]) ? (float)$prices[1] : null,
'priceCurrency' => 'GBP'
],
'availability' => 'https://schema.org/InStock',
'validFrom' => date('Y-m-d')
];
}
// Add features/service output if provided
if (!empty($features)) {
$schema['hasOfferCatalog'] = [
'@type' => 'OfferCatalog',
'name' => $serviceName . ' Features',
'itemListElement' => array_map(function($feature) {
return [
'@type' => 'Offer',
'itemOffered' => [
'@type' => 'Service',
'name' => $feature
]
];
}, $features)
];
}
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Predefined service configurations for consistency
*/
$serviceConfigs = [
'web-scraping' => [
'name' => 'Web Scraping Services UK',
'description' => 'Professional web scraping and data extraction services for UK businesses. Automated data collection from websites with 99.8% accuracy and full GDPR compliance.',
'url' => 'https://ukdataservices.co.uk/services/web-scraping',
'serviceType' => 'Web Scraping',
'priceRange' => '500-50000',
'features' => [
'Automated data extraction',
'Real-time monitoring',
'GDPR-compliant collection',
'Custom API delivery',
'Multi-format output'
]
],
'competitive-intelligence' => [
'name' => 'Competitive Intelligence Services UK',
'description' => 'Strategic competitive intelligence and market analysis services. Monitor competitors, track market trends, and gain actionable business insights.',
'url' => 'https://ukdataservices.co.uk/services/competitive-intelligence',
'serviceType' => 'Competitive Intelligence',
'priceRange' => '1000-25000',
'features' => [
'Competitor monitoring',
'Market trend analysis',
'Price tracking',
'Product intelligence',
'Strategic reporting'
]
],
'price-monitoring' => [
'name' => 'Price Monitoring Services UK',
'description' => 'Real-time price monitoring and competitor price tracking services. E-commerce pricing intelligence for UK retailers and brands.',
'url' => 'https://ukdataservices.co.uk/services/price-monitoring',
'serviceType' => 'Price Monitoring',
'priceRange' => '500-15000',
'features' => [
'Real-time price tracking',
'Competitor price alerts',
'MAP monitoring',
'Historical price analysis',
'Automated reporting'
]
],
'data-cleaning' => [
'name' => 'Data Cleaning & Validation Services UK',
'description' => 'Professional data cleaning, validation, and standardisation services. Transform messy data into accurate, structured datasets.',
'url' => 'https://ukdataservices.co.uk/services/data-cleaning',
'serviceType' => 'Data Cleaning',
'priceRange' => '500-20000',
'features' => [
'Duplicate removal',
'Data standardisation',
'Format validation',
'Error correction',
'Quality assurance'
]
],
'data-analytics' => [
'name' => 'Data Analytics Services UK',
'description' => 'Business intelligence and data analytics solutions for UK enterprises. Transform raw data into actionable insights.',
'url' => 'https://ukdataservices.co.uk/services/data-analytics',
'serviceType' => 'Data Analytics',
'priceRange' => '1000-30000',
'features' => [
'Business intelligence',
'Predictive analytics',
'Custom dashboards',
'Data visualisation',
'Strategic insights'
]
],
'api-development' => [
'name' => 'API Development Services UK',
'description' => 'Custom API development and data integration services. Build robust APIs to connect your systems and automate data workflows.',
'url' => 'https://ukdataservices.co.uk/services/api-development',
'serviceType' => 'API Development',
'priceRange' => '2000-40000',
'features' => [
'Custom API design',
'System integration',
'Real-time data feeds',
'Authentication systems',
'Documentation'
]
],
'property-data-extraction' => [
'name' => 'UK Property Data Extraction Services',
'description' => 'Professional property data extraction from UK property portals including Rightmove, Zoopla, and OnTheMarket. GDPR-compliant property market intelligence.',
'url' => 'https://ukdataservices.co.uk/services/property-data-extraction',
'serviceType' => 'Property Data Extraction',
'priceRange' => '1000-25000',
'features' => [
'Property portal data extraction',
'Market analysis',
'Investment research data',
'Rental market intelligence',
'Commercial property data'
]
],
'financial-data-services' => [
'name' => 'Financial Data Services UK',
'description' => 'FCA-aware financial data services for hedge funds, asset managers, and investment firms. Market data extraction and alternative data solutions.',
'url' => 'https://ukdataservices.co.uk/services/financial-data-services',
'serviceType' => 'Financial Data Services',
'priceRange' => '5000-100000',
'features' => [
'Market data extraction',
'Alternative data feeds',
'Securities monitoring',
'Compliance-aware collection',
'API delivery'
]
]
];
// If $serviceData is set, output the schema automatically
if (isset($serviceData) && is_array($serviceData)) {
echo generateServiceSchema(
$serviceData['name'],
$serviceData['description'],
$serviceData['url'],
$serviceData['serviceType'],
$serviceData['priceRange'] ?? null,
$serviceData['features'] ?? []
);
}

View File

@@ -1,233 +0,0 @@
<?php
/**
* URL Configuration
* Centralized URL mapping for internal linking consistency
*
* Usage:
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/url-config.php');
* echo $urlMap['services']['web-scraping'];
*/
$baseUrl = 'https://ukdataservices.co.uk';
/**
* Complete URL map for the site
*/
$urlMap = [
'home' => '/',
'about' => '/about',
'quote' => '/quote',
'faq' => '/faq',
'blog' => '/blog',
'contact' => '/#contact',
'project-types' => '/project-types',
'case-studies' => '/case-studies',
// Services
'services' => [
'index' => '/#services',
'web-scraping' => '/services/web-scraping',
'competitive-intelligence' => '/services/competitive-intelligence',
'price-monitoring' => '/services/price-monitoring',
'data-cleaning' => '/services/data-cleaning',
'data-analytics' => '/services/data-analytics',
'api-development' => '/services/api-development',
'property-data-extraction' => '/services/property-data-extraction',
'financial-data-services' => '/services/financial-data-services'
],
// Locations
'locations' => [
'index' => '/locations',
'london' => '/locations/london',
'manchester' => '/locations/manchester',
'birmingham' => '/locations/birmingham',
'edinburgh' => '/locations/edinburgh',
'cardiff' => '/locations/cardiff'
],
// Blog categories
'blog-categories' => [
'web-scraping' => '/blog/categories/web-scraping',
'data-analytics' => '/blog/categories/data-analytics',
'business-intelligence' => '/blog/categories/business-intelligence',
'compliance' => '/blog/categories/compliance',
'industry-insights' => '/blog/categories/industry-insights',
'technology' => '/blog/categories/technology',
'case-studies' => '/blog/categories/case-studies'
],
// Legal pages
'legal' => [
'privacy-policy' => '/privacy-policy',
'terms-of-service' => '/terms-of-service',
'cookie-policy' => '/cookie-policy',
'gdpr-compliance' => '/gdpr-compliance'
]
];
/**
* Service metadata for internal linking and SEO
*/
$serviceData = [
'web-scraping' => [
'url' => '/services/web-scraping',
'title' => 'Web Scraping Services',
'shortTitle' => 'Web Scraping',
'description' => 'Professional web scraping and data extraction services',
'icon' => 'icon-web-scraping-v2.svg'
],
'competitive-intelligence' => [
'url' => '/services/competitive-intelligence',
'title' => 'Competitive Intelligence',
'shortTitle' => 'Competitive Intelligence',
'description' => 'Market analysis and competitor monitoring services',
'icon' => 'icon-analytics.svg'
],
'price-monitoring' => [
'url' => '/services/price-monitoring',
'title' => 'Price Monitoring',
'shortTitle' => 'Price Monitoring',
'description' => 'Real-time price tracking and competitor pricing alerts',
'icon' => 'icon-price-monitoring.svg'
],
'data-cleaning' => [
'url' => '/services/data-cleaning',
'title' => 'Data Cleaning & Validation',
'shortTitle' => 'Data Cleaning',
'description' => 'Professional data cleaning and quality assurance',
'icon' => 'icon-data-processing.svg'
],
'data-analytics' => [
'url' => '/services/data-analytics',
'title' => 'Data Analytics',
'shortTitle' => 'Analytics',
'description' => 'Business intelligence and data analytics solutions',
'icon' => 'icon-analytics.svg'
],
'api-development' => [
'url' => '/services/api-development',
'title' => 'API Development',
'shortTitle' => 'API Development',
'description' => 'Custom API development and system integration',
'icon' => 'icon-automation.svg'
],
'property-data-extraction' => [
'url' => '/services/property-data-extraction',
'title' => 'Property Data Extraction',
'shortTitle' => 'Property Data',
'description' => 'UK property market data from Rightmove, Zoopla, OnTheMarket',
'icon' => 'icon-property.svg'
],
'financial-data-services' => [
'url' => '/services/financial-data-services',
'title' => 'Financial Data Services',
'shortTitle' => 'Financial Data',
'description' => 'FCA-compliant financial and market data extraction',
'icon' => 'icon-financial.svg'
]
];
/**
* Location metadata for internal linking
*/
$locationData = [
'london' => [
'url' => '/locations/london',
'title' => 'London',
'region' => 'Greater London',
'description' => 'Web scraping and data analytics services in London'
],
'manchester' => [
'url' => '/locations/manchester',
'title' => 'Manchester',
'region' => 'Greater Manchester',
'description' => 'Data analytics and web scraping services in Manchester'
],
'birmingham' => [
'url' => '/locations/birmingham',
'title' => 'Birmingham',
'region' => 'West Midlands',
'description' => 'Data services and business intelligence in Birmingham'
],
'edinburgh' => [
'url' => '/locations/edinburgh',
'title' => 'Edinburgh',
'region' => 'Scotland',
'description' => 'Data analytics and web scraping services in Edinburgh'
],
'cardiff' => [
'url' => '/locations/cardiff',
'title' => 'Cardiff',
'region' => 'Wales',
'description' => 'Data services and business intelligence in Cardiff'
]
];
/**
* Related services mapping for cross-linking
*/
$relatedServices = [
'web-scraping' => ['competitive-intelligence', 'price-monitoring', 'data-cleaning'],
'competitive-intelligence' => ['web-scraping', 'price-monitoring', 'data-analytics'],
'price-monitoring' => ['web-scraping', 'competitive-intelligence', 'data-analytics'],
'data-cleaning' => ['web-scraping', 'data-analytics', 'api-development'],
'data-analytics' => ['competitive-intelligence', 'data-cleaning', 'api-development'],
'api-development' => ['web-scraping', 'data-cleaning', 'data-analytics'],
'property-data-extraction' => ['web-scraping', 'data-cleaning', 'competitive-intelligence'],
'financial-data-services' => ['web-scraping', 'data-analytics', 'api-development']
];
/**
* Get full URL with base URL
*
* @param string $path Relative path
* @return string Full URL
*/
function getFullUrl($path) {
global $baseUrl;
return $baseUrl . $path;
}
/**
* Get service URL by key
*
* @param string $serviceKey Service identifier
* @return string Service URL
*/
function getServiceUrl($serviceKey) {
global $urlMap;
return $urlMap['services'][$serviceKey] ?? '/#services';
}
/**
* Get location URL by key
*
* @param string $locationKey Location identifier
* @return string Location URL
*/
function getLocationUrl($locationKey) {
global $urlMap;
return $urlMap['locations'][$locationKey] ?? '/';
}
/**
* Get related services for a given service
*
* @param string $serviceKey Current service key
* @return array Array of related service data
*/
function getRelatedServices($serviceKey) {
global $relatedServices, $serviceData;
$related = $relatedServices[$serviceKey] ?? [];
$result = [];
foreach ($related as $relatedKey) {
if (isset($serviceData[$relatedKey])) {
$result[] = $serviceData[$relatedKey];
}
}
return $result;
}

View File

@@ -1,164 +0,0 @@
<?php
/**
* Meta Tags Helper
* Generates optimized meta tags for SEO
*
* Usage:
* $metaData = [
* 'title' => 'Page Title',
* 'description' => 'Page description...',
* 'canonicalUrl' => 'https://ukdataservices.co.uk/page',
* 'ogImage' => '/assets/images/og-image.jpg',
* 'type' => 'website', // or 'article'
* 'articleData' => [...] // optional for articles
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/meta-tags.php');
*/
/**
* Generate complete meta tags for a page
*
* @param string $title Page title (will append brand if not already included)
* @param string $description Meta description (max 160 chars recommended)
* @param string $canonicalUrl Canonical URL for the page
* @param string|null $ogImage Open Graph image URL
* @param array|null $articleData Article-specific data for blog posts
* @param string $type Page type (website, article, service)
* @return string HTML meta tags
*/
function generateMetaTags($title, $description, $canonicalUrl, $ogImage = null, $articleData = null, $type = 'website') {
$baseUrl = 'https://ukdataservices.co.uk';
$siteName = 'UK Data Services';
$defaultImage = $baseUrl . '/assets/images/ukds-main-logo.png';
$twitterHandle = '@ukdataservices';
// Ensure title includes brand name
$fullTitle = $title;
if (strpos(strtolower($title), 'uk data services') === false) {
$fullTitle = $title . ' | UK Data Services';
}
// Truncate description if too long
if (strlen($description) > 160) {
$description = substr($description, 0, 157) . '...';
}
// Use provided image or default
$imageUrl = $ogImage ? (strpos($ogImage, 'http') === 0 ? $ogImage : $baseUrl . $ogImage) : $defaultImage;
$output = '';
// Basic meta tags
$output .= '<title>' . htmlspecialchars($fullTitle) . '</title>' . "\n";
$output .= ' <meta name="description" content="' . htmlspecialchars($description) . '">' . "\n";
$output .= ' <meta name="author" content="UK Data Services">' . "\n";
$output .= ' <meta name="robots" content="index, follow">' . "\n";
$output .= ' <meta name="googlebot" content="index, follow">' . "\n";
$output .= ' <link rel="canonical" href="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
// Open Graph tags
$output .= "\n <!-- Open Graph / Facebook -->\n";
$output .= ' <meta property="og:type" content="' . ($type === 'article' ? 'article' : 'website') . '">' . "\n";
$output .= ' <meta property="og:url" content="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
$output .= ' <meta property="og:title" content="' . htmlspecialchars($title) . '">' . "\n";
$output .= ' <meta property="og:description" content="' . htmlspecialchars($description) . '">' . "\n";
$output .= ' <meta property="og:image" content="' . htmlspecialchars($imageUrl) . '">' . "\n";
$output .= ' <meta property="og:image:width" content="1200">' . "\n";
$output .= ' <meta property="og:image:height" content="630">' . "\n";
$output .= ' <meta property="og:site_name" content="' . $siteName . '">' . "\n";
$output .= ' <meta property="og:locale" content="en_GB">' . "\n";
// Twitter Card tags
$output .= "\n <!-- Twitter Card -->\n";
$output .= ' <meta name="twitter:card" content="summary_large_image">' . "\n";
$output .= ' <meta name="twitter:site" content="' . $twitterHandle . '">' . "\n";
$output .= ' <meta name="twitter:url" content="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
$output .= ' <meta name="twitter:title" content="' . htmlspecialchars($title) . '">' . "\n";
$output .= ' <meta name="twitter:description" content="' . htmlspecialchars($description) . '">' . "\n";
$output .= ' <meta name="twitter:image" content="' . htmlspecialchars($imageUrl) . '">' . "\n";
// Article-specific tags
if ($articleData && $type === 'article') {
$output .= "\n <!-- Article Meta -->\n";
if (isset($articleData['datePublished'])) {
$output .= ' <meta property="article:published_time" content="' . $articleData['datePublished'] . 'T09:00:00+00:00">' . "\n";
}
if (isset($articleData['dateModified'])) {
$output .= ' <meta property="article:modified_time" content="' . $articleData['dateModified'] . 'T09:00:00+00:00">' . "\n";
}
if (isset($articleData['author'])) {
$output .= ' <meta property="article:author" content="' . htmlspecialchars($articleData['author']) . '">' . "\n";
}
if (isset($articleData['section'])) {
$output .= ' <meta property="article:section" content="' . htmlspecialchars($articleData['section']) . '">' . "\n";
}
if (isset($articleData['tags']) && is_array($articleData['tags'])) {
foreach ($articleData['tags'] as $tag) {
$output .= ' <meta property="article:tag" content="' . htmlspecialchars($tag) . '">' . "\n";
}
}
}
return $output;
}
/**
* Generate geo meta tags for location pages
*/
function generateGeoMetaTags($city, $region, $latitude, $longitude) {
$output = "\n <!-- Geo Meta Tags -->\n";
$output .= ' <meta name="geo.region" content="GB">' . "\n";
$output .= ' <meta name="geo.placename" content="' . htmlspecialchars($city) . '">' . "\n";
$output .= ' <meta name="geo.position" content="' . $latitude . ';' . $longitude . '">' . "\n";
$output .= ' <meta name="ICBM" content="' . $latitude . ', ' . $longitude . '">' . "\n";
return $output;
}
/**
* Generate hreflang tags (for potential future internationalization)
*/
function generateHreflangTags($canonicalUrl) {
$output = "\n <!-- Hreflang -->\n";
$output .= ' <link rel="alternate" hreflang="en-GB" href="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
$output .= ' <link rel="alternate" hreflang="x-default" href="' . htmlspecialchars($canonicalUrl) . '">' . "\n";
return $output;
}
/**
* Output standard favicon and manifest links
*/
function generateFaviconTags() {
$output = "\n <!-- Favicon and App Icons -->\n";
$output .= ' <link rel="icon" type="image/svg+xml" href="/assets/images/favicon.svg">' . "\n";
$output .= ' <link rel="icon" type="image/svg+xml" sizes="16x16" href="/assets/images/favicon-16x16.svg">' . "\n";
$output .= ' <link rel="icon" type="image/svg+xml" sizes="32x32" href="/assets/images/favicon-32x32.svg">' . "\n";
$output .= ' <link rel="apple-touch-icon" sizes="180x180" href="/assets/images/apple-touch-icon.svg">' . "\n";
$output .= ' <link rel="manifest" href="/manifest.json">' . "\n";
$output .= ' <meta name="theme-color" content="#144784">' . "\n";
$output .= ' <meta name="msapplication-TileColor" content="#179e83">' . "\n";
return $output;
}
/**
* Generate preconnect/prefetch hints for performance
*/
function generateResourceHints() {
$output = "\n <!-- Resource Hints -->\n";
$output .= ' <link rel="preconnect" href="https://fonts.googleapis.com">' . "\n";
$output .= ' <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' . "\n";
$output .= ' <link rel="dns-prefetch" href="https://www.google-analytics.com">' . "\n";
$output .= ' <link rel="dns-prefetch" href="https://www.googletagmanager.com">' . "\n";
return $output;
}
// If $metaData is set, output meta tags automatically
if (isset($metaData) && is_array($metaData)) {
echo generateMetaTags(
$metaData['title'],
$metaData['description'],
$metaData['canonicalUrl'],
$metaData['ogImage'] ?? null,
$metaData['articleData'] ?? null,
$metaData['type'] ?? 'website'
);
}

View File

@@ -1,198 +0,0 @@
<?php
/**
* Article Schema Component
* Generates Article structured data for blog posts
*
* Usage:
* $articleData = [
* 'title' => 'Article Title',
* 'description' => 'Article description...',
* 'datePublished' => '2024-01-15',
* 'dateModified' => '2024-01-20',
* 'authorName' => 'John Smith',
* 'imageUrl' => 'https://example.com/image.jpg',
* 'articleUrl' => 'https://example.com/article'
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/article-schema.php');
*/
/**
* Generate Article Schema JSON-LD
*
* @param string $title Article title
* @param string $description Article description/excerpt
* @param string $datePublished Publication date (Y-m-d format)
* @param string $dateModified Last modified date (Y-m-d format)
* @param string $authorName Author's name
* @param string $imageUrl Featured image URL
* @param string $articleUrl Canonical article URL
* @param string $category Optional article category
* @param array $keywords Optional array of keywords
* @return string JSON-LD script tag
*/
function generateArticleSchema($title, $description, $datePublished, $dateModified, $authorName, $imageUrl, $articleUrl, $category = null, $keywords = []) {
$baseUrl = 'https://ukdataservices.co.uk';
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Article',
'@id' => $articleUrl . '#article',
'headline' => $title,
'description' => $description,
'url' => $articleUrl,
'datePublished' => $datePublished . 'T09:00:00+00:00',
'dateModified' => $dateModified . 'T09:00:00+00:00',
'author' => [
'@type' => 'Person',
'name' => $authorName,
'url' => $baseUrl . '/about'
],
'publisher' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization',
'name' => 'UK Data Services',
'logo' => [
'@type' => 'ImageObject',
'url' => $baseUrl . '/assets/images/ukds-main-logo.png'
]
],
'image' => [
'@type' => 'ImageObject',
'url' => $imageUrl,
'width' => 1200,
'height' => 630
],
'mainEntityOfPage' => [
'@type' => 'WebPage',
'@id' => $articleUrl
],
'isPartOf' => [
'@type' => 'Blog',
'@id' => $baseUrl . '/blog/#blog',
'name' => 'UK Data Services Blog',
'publisher' => [
'@id' => $baseUrl . '/#organization'
]
],
'inLanguage' => 'en-GB'
];
// Add category if provided
if ($category) {
$schema['articleSection'] = $category;
}
// Add keywords if provided
if (!empty($keywords)) {
$schema['keywords'] = implode(', ', $keywords);
}
// Add word count estimate based on description length (rough estimate)
$schema['wordCount'] = max(500, strlen($description) * 5);
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Generate BlogPosting Schema (more specific than Article)
*/
function generateBlogPostingSchema($title, $description, $datePublished, $dateModified, $authorName, $imageUrl, $articleUrl, $category = null, $keywords = []) {
$baseUrl = 'https://ukdataservices.co.uk';
$schema = [
'@context' => 'https://schema.org',
'@type' => 'BlogPosting',
'@id' => $articleUrl . '#blogposting',
'headline' => $title,
'description' => $description,
'url' => $articleUrl,
'datePublished' => $datePublished . 'T09:00:00+00:00',
'dateModified' => $dateModified . 'T09:00:00+00:00',
'author' => [
'@type' => 'Person',
'name' => $authorName,
'url' => $baseUrl . '/about',
'worksFor' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization'
]
],
'publisher' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization',
'name' => 'UK Data Services',
'logo' => [
'@type' => 'ImageObject',
'url' => $baseUrl . '/assets/images/ukds-main-logo.png',
'width' => 300,
'height' => 100
]
],
'image' => [
'@type' => 'ImageObject',
'url' => $imageUrl,
'width' => 1200,
'height' => 630
],
'mainEntityOfPage' => [
'@type' => 'WebPage',
'@id' => $articleUrl
],
'isPartOf' => [
'@type' => 'Blog',
'@id' => $baseUrl . '/blog/#blog',
'name' => 'UK Data Services Blog'
],
'inLanguage' => 'en-GB'
];
if ($category) {
$schema['articleSection'] = $category;
}
if (!empty($keywords)) {
$schema['keywords'] = implode(', ', $keywords);
}
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Author configurations for the site
*/
$authorProfiles = [
'uk-data-services-team' => [
'name' => 'UK Data Services Team',
'role' => 'Data Intelligence Experts',
'description' => 'Our team of certified data professionals and engineers providing expert guidance on web scraping, data analytics, and business intelligence.'
],
'technical-team' => [
'name' => 'UK Data Services Technical Team',
'role' => 'Senior Data Engineers',
'description' => 'Expert engineers specializing in web scraping technologies, data pipelines, and enterprise data solutions.'
],
'compliance-team' => [
'name' => 'UK Data Services Compliance Team',
'role' => 'Data Protection Specialists',
'description' => 'Specialists in GDPR compliance, data protection, and regulatory requirements for data collection.'
]
];
// If $articleData is set, output the schema automatically
if (isset($articleData) && is_array($articleData)) {
echo generateArticleSchema(
$articleData['title'],
$articleData['description'],
$articleData['datePublished'],
$articleData['dateModified'] ?? $articleData['datePublished'],
$articleData['authorName'] ?? 'UK Data Services Team',
$articleData['imageUrl'],
$articleData['articleUrl'],
$articleData['category'] ?? null,
$articleData['keywords'] ?? []
);
}

View File

@@ -1,151 +0,0 @@
<?php
/**
* FAQ Schema Component
* Generates FAQPage structured data for FAQ sections
*
* Usage:
* $faqs = [
* ['question' => 'What is web scraping?', 'answer' => 'Web scraping is...'],
* ['question' => 'How much does it cost?', 'answer' => 'Pricing varies...']
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/faq-schema.php');
*/
/**
* Generate FAQPage Schema JSON-LD
*
* @param array $faqs Array of Q&A pairs with 'question' and 'answer' keys
* @param string|null $pageUrl Optional canonical URL for the FAQ page
* @param string|null $pageName Optional name for the FAQ page
* @return string JSON-LD script tag
*/
function generateFAQSchema($faqs, $pageUrl = null, $pageName = null) {
if (empty($faqs)) {
return '';
}
$schema = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage'
];
// Add page identifier if URL provided
if ($pageUrl) {
$schema['@id'] = $pageUrl . '#faqpage';
$schema['url'] = $pageUrl;
}
// Add page name if provided
if ($pageName) {
$schema['name'] = $pageName;
}
// Build main entity array
$schema['mainEntity'] = array_map(function($faq) {
return [
'@type' => 'Question',
'name' => $faq['question'],
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $faq['answer']
]
];
}, $faqs);
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Common FAQs for different page types
*/
$commonFAQs = [
'general' => [
[
'question' => 'What is web scraping and how can it benefit my business?',
'answer' => 'Web scraping is the automated process of extracting data from websites. It benefits businesses by providing competitive intelligence, automating data collection, enabling real-time price monitoring, and supporting strategic decision-making with accurate market data.'
],
[
'question' => 'Is web scraping legal in the UK?',
'answer' => 'Yes, web scraping is legal in the UK when conducted properly. We ensure full compliance with UK Data Protection Act 2018, GDPR, website terms of service, and industry best practices. We only collect publicly available data and respect robots.txt directives.'
],
[
'question' => 'How do you ensure data accuracy?',
'answer' => 'We maintain a 99.8% accuracy rate through advanced validation algorithms, multi-layer verification processes, regular monitoring, and comprehensive testing before delivery. Each dataset undergoes rigorous quality assurance checks.'
],
[
'question' => 'What data formats do you provide?',
'answer' => 'We deliver data in multiple formats including Excel (XLSX/XLS), CSV, JSON, XML, SQL database dumps, and custom formats. We also offer real-time data feeds and API access for ongoing projects.'
],
[
'question' => 'How much do your services cost?',
'answer' => 'Pricing varies based on project complexity: Simple extraction projects start from £500-£2,000, medium complexity projects range from £2,000-£10,000, and enterprise solutions are £10,000+. We provide custom quotes based on your specific requirements.'
]
],
'pricing' => [
[
'question' => 'What factors affect the cost of web scraping services?',
'answer' => 'Costs depend on several factors: the number and complexity of target websites, data volume required, frequency of updates, anti-bot measures to navigate, data cleaning requirements, and delivery format preferences.'
],
[
'question' => 'Do you offer monthly retainer packages?',
'answer' => 'Yes, we offer flexible monthly retainer packages for ongoing data collection needs. These include regular updates, priority support, and often provide better value than one-off projects for continuous monitoring requirements.'
],
[
'question' => 'Is there a minimum project value?',
'answer' => 'Our minimum project value is £500. This ensures we can deliver quality work with proper attention to accuracy, compliance, and client requirements.'
]
],
'compliance' => [
[
'question' => 'How do you handle GDPR compliance?',
'answer' => 'GDPR compliance is central to our operations. We only collect personal data when legally justified, follow data minimisation principles, implement robust security measures, maintain clear data retention policies, and respect data subject rights.'
],
[
'question' => 'Do you scrape personal data?',
'answer' => 'We only collect personal data when there is a legitimate legal basis, such as legitimate business interests or consent. We follow strict GDPR guidelines and advise clients on compliant data collection strategies.'
],
[
'question' => 'What security measures do you have in place?',
'answer' => 'We implement enterprise-grade security including encrypted data transfer (SSL/TLS), secure data storage, access controls, and regular security audits.'
]
],
'property-data' => [
[
'question' => 'Can you extract data from Rightmove and Zoopla?',
'answer' => 'Yes, we can extract publicly available property data from UK property portals including Rightmove, Zoopla, OnTheMarket, and others. We ensure compliance with each platform\'s terms of service and UK data protection laws.'
],
[
'question' => 'What property data can you collect?',
'answer' => 'We can collect property listings, prices, property features, location data, historical price changes, rental yields, local area information, and market trends. Custom data requirements can be discussed during consultation.'
],
[
'question' => 'How often can property data be updated?',
'answer' => 'We offer daily, weekly, or monthly property data updates depending on your needs. Real-time monitoring is also available for time-sensitive market intelligence requirements.'
]
],
'financial-data' => [
[
'question' => 'Do you provide FCA-compliant financial data services?',
'answer' => 'Yes, our financial data services are designed with FCA regulations in mind. We help hedge funds, asset managers, and investment firms collect market data while maintaining compliance with applicable financial regulations.'
],
[
'question' => 'What types of alternative data do you provide?',
'answer' => 'We provide various alternative data sources including web traffic data, sentiment analysis, pricing data, job posting trends, satellite imagery analysis, and custom data feeds tailored to investment strategies.'
],
[
'question' => 'Can you provide historical financial data?',
'answer' => 'Yes, we can extract and compile historical financial data where publicly available. This includes historical pricing, company filings, news archives, and market trend data for backtesting and analysis purposes.'
]
]
];
// If $faqs is set, output the schema automatically
if (isset($faqs) && is_array($faqs)) {
echo generateFAQSchema(
$faqs,
$faqPageUrl ?? null,
$faqPageName ?? null
);
}

View File

@@ -1,233 +0,0 @@
<?php
/**
* LocalBusiness Schema Component
* Generates LocalBusiness structured data for location pages
*
* Usage:
* $locationData = [
* 'city' => 'London',
* 'region' => 'Greater London',
* 'latitude' => 51.5074,
* 'longitude' => -0.1278,
* 'services' => ['Web Scraping', 'Data Analytics']
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/local-business-schema.php');
*/
/**
* Generate LocalBusiness Schema JSON-LD for city/location pages
*
* @param string $city The city name
* @param string $region The region/county name
* @param array $services Array of service names offered in this location
* @param float|null $latitude Optional latitude coordinate
* @param float|null $longitude Optional longitude coordinate
* @return string JSON-LD script tag
*/
function generateLocalBusinessSchema($city, $region, $services = [], $latitude = null, $longitude = null) {
$baseUrl = 'https://ukdataservices.co.uk';
$citySlug = strtolower(str_replace(' ', '-', $city));
$schema = [
'@context' => 'https://schema.org',
'@type' => 'LocalBusiness',
'@id' => $baseUrl . '/locations/' . $citySlug . '#localbusiness',
'name' => 'UK Data Services - ' . $city,
'description' => 'Professional web scraping, data extraction, and business intelligence services for ' . $city . ' businesses. GDPR-compliant data solutions across ' . $region . '.',
'url' => $baseUrl . '/locations/' . $citySlug,
'telephone' => '+44 1692 689150',
'email' => 'info@ukdataservices.co.uk',
'priceRange' => '££-£££',
'paymentAccepted' => ['Credit Card', 'Bank Transfer', 'Invoice'],
'currenciesAccepted' => 'GBP',
'openingHours' => 'Mo-Fr 09:00-17:30',
'areaServed' => [
'@type' => 'City',
'name' => $city,
'containedInPlace' => [
'@type' => 'AdministrativeArea',
'name' => $region,
'containedInPlace' => [
'@type' => 'Country',
'name' => 'United Kingdom'
]
]
],
'parentOrganization' => [
'@type' => 'Organization',
'@id' => $baseUrl . '/#organization',
'name' => 'UK Data Services'
],
'image' => $baseUrl . '/assets/images/ukds-main-logo.png',
'sameAs' => [
'https://www.linkedin.com/company/ukdataservices',
'https://twitter.com/ukdataservices'
]
];
// Add geo coordinates if provided
if ($latitude && $longitude) {
$schema['geo'] = [
'@type' => 'GeoCoordinates',
'latitude' => $latitude,
'longitude' => $longitude
];
}
// Add aggregate rating
$schema['aggregateRating'] = [
'@type' => 'AggregateRating',
'ratingValue' => '4.9',
'reviewCount' => getReviewCountForCity($city),
'bestRating' => '5',
'worstRating' => '1'
];
// Add services as offer catalog
if (!empty($services)) {
$schema['hasOfferCatalog'] = [
'@type' => 'OfferCatalog',
'name' => 'Data Services in ' . $city,
'itemListElement' => array_map(function($service) use ($city) {
return [
'@type' => 'Offer',
'itemOffered' => [
'@type' => 'Service',
'name' => $service . ' ' . $city
]
];
}, $services)
];
}
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Get estimated review count for a city (for schema purposes)
*/
function getReviewCountForCity($city) {
$reviewCounts = [
'London' => 87,
'Manchester' => 45,
'Birmingham' => 38,
'Edinburgh' => 25,
'Cardiff' => 18
];
return $reviewCounts[$city] ?? 20;
}
/**
* Predefined location configurations
*/
$locationConfigs = [
'london' => [
'city' => 'London',
'region' => 'Greater London',
'latitude' => 51.5074,
'longitude' => -0.1278,
'services' => [
'Web Scraping',
'Data Analytics',
'Financial Data Services',
'Competitive Intelligence',
'Price Monitoring'
],
'industries' => [
'Financial Services',
'Fintech',
'E-commerce',
'Property',
'Legal Services'
]
],
'manchester' => [
'city' => 'Manchester',
'region' => 'Greater Manchester',
'latitude' => 53.4808,
'longitude' => -2.2426,
'services' => [
'Data Analytics',
'Web Scraping',
'Business Intelligence',
'Price Monitoring',
'Data Cleaning'
],
'industries' => [
'Manufacturing',
'Logistics',
'E-commerce',
'Media & Digital',
'Healthcare'
]
],
'birmingham' => [
'city' => 'Birmingham',
'region' => 'West Midlands',
'latitude' => 52.4862,
'longitude' => -1.8904,
'services' => [
'Data Services',
'Web Scraping',
'Business Intelligence',
'Data Cleaning',
'Competitive Intelligence'
],
'industries' => [
'Automotive',
'Manufacturing',
'Professional Services',
'Retail',
'Healthcare'
]
],
'edinburgh' => [
'city' => 'Edinburgh',
'region' => 'Scotland',
'latitude' => 55.9533,
'longitude' => -3.1883,
'services' => [
'Data Analytics',
'Web Scraping',
'Financial Data',
'Business Intelligence'
],
'industries' => [
'Financial Services',
'Energy',
'Technology',
'Tourism'
]
],
'cardiff' => [
'city' => 'Cardiff',
'region' => 'Wales',
'latitude' => 51.4816,
'longitude' => -3.1791,
'services' => [
'Data Services',
'Web Scraping',
'Business Intelligence',
'Data Cleaning'
],
'industries' => [
'Public Sector',
'Financial Services',
'Media',
'Manufacturing'
]
]
];
// If $locationData is set, output the schema automatically
if (isset($locationData) && is_array($locationData)) {
echo generateLocalBusinessSchema(
$locationData['city'],
$locationData['region'],
$locationData['services'] ?? [],
$locationData['latitude'] ?? null,
$locationData['longitude'] ?? null
);
}

View File

@@ -1,108 +0,0 @@
<?php
/**
* Organization Schema Component
* Generates Organization structured data for improved SEO
*
* Usage: Include this file in the <head> of every page
* <?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/organization-schema.php'); ?>
*/
$organizationSchema = [
'@context' => 'https://schema.org',
'@type' => 'Organization',
'@id' => 'https://ukdataservices.co.uk/#organization',
'name' => 'UK Data Services',
'legalName' => 'UK Data Services Limited',
'url' => 'https://ukdataservices.co.uk',
'logo' => [
'@type' => 'ImageObject',
'url' => 'https://ukdataservices.co.uk/assets/images/ukds-main-logo.png',
'width' => 300,
'height' => 100
],
'image' => 'https://ukdataservices.co.uk/assets/images/ukds-main-logo.png',
'description' => 'Enterprise web scraping and data analytics services for UK businesses. Specialising in competitive intelligence, price monitoring, and GDPR-compliant data extraction.',
'telephone' => '+44 1692 689150',
'email' => 'info@ukdataservices.co.uk',
'address' => [
'@type' => 'PostalAddress',
'streetAddress' => 'Professional Data Services Centre',
'addressLocality' => 'London',
'addressRegion' => 'England',
'postalCode' => 'EC1A 1BB',
'addressCountry' => 'GB'
],
'geo' => [
'@type' => 'GeoCoordinates',
'latitude' => 51.5074,
'longitude' => -0.1278
],
'areaServed' => [
[
'@type' => 'Country',
'name' => 'United Kingdom'
],
[
'@type' => 'City',
'name' => 'London'
],
[
'@type' => 'City',
'name' => 'Manchester'
],
[
'@type' => 'City',
'name' => 'Birmingham'
],
[
'@type' => 'City',
'name' => 'Edinburgh'
],
[
'@type' => 'City',
'name' => 'Cardiff'
]
],
'sameAs' => [
'https://www.linkedin.com/company/ukdataservices',
'https://twitter.com/ukdataservices'
],
'contactPoint' => [
[
'@type' => 'ContactPoint',
'telephone' => '+44 1692 689150',
'contactType' => 'sales',
'availableLanguage' => 'English',
'areaServed' => 'GB',
'hoursAvailable' => [
'@type' => 'OpeningHoursSpecification',
'dayOfWeek' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
'opens' => '09:00',
'closes' => '17:30'
]
],
[
'@type' => 'ContactPoint',
'email' => 'info@ukdataservices.co.uk',
'contactType' => 'customer service',
'availableLanguage' => 'English',
'areaServed' => 'GB'
]
],
'foundingDate' => '2018',
'numberOfEmployees' => [
'@type' => 'QuantitativeValue',
'value' => '15'
],
'aggregateRating' => [
'@type' => 'AggregateRating',
'ratingValue' => '4.9',
'reviewCount' => '127',
'bestRating' => '5',
'worstRating' => '1'
]
];
?>
<script type="application/ld+json">
<?php echo json_encode($organizationSchema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); ?>
</script>

View File

@@ -1,196 +0,0 @@
<?php
/**
* Review Schema Component
* Generates Review and AggregateRating structured data
*
* Usage:
* $reviews = [
* ['author' => 'John Smith', 'reviewBody' => 'Great service!', 'ratingValue' => 5],
* ['author' => 'Jane Doe', 'reviewBody' => 'Excellent work', 'ratingValue' => 5]
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/review-schema.php');
*/
/**
* Generate Review Schema JSON-LD with AggregateRating
*
* @param array $reviews Array of review data
* @param string $itemName Name of the item being reviewed
* @param string $itemType Schema type (Organization, Service, Product, etc.)
* @param string|null $itemUrl URL of the item being reviewed
* @return string JSON-LD script tag
*/
function generateReviewSchema($reviews, $itemName = 'UK Data Services', $itemType = 'Organization', $itemUrl = null) {
if (empty($reviews)) {
return '';
}
$baseUrl = 'https://ukdataservices.co.uk';
// Calculate aggregate rating
$totalRating = 0;
$reviewCount = count($reviews);
foreach ($reviews as $review) {
$totalRating += $review['ratingValue'] ?? 5;
}
$averageRating = round($totalRating / $reviewCount, 1);
$schema = [
'@context' => 'https://schema.org',
'@type' => $itemType,
'name' => $itemName,
'url' => $itemUrl ?? $baseUrl,
'aggregateRating' => [
'@type' => 'AggregateRating',
'ratingValue' => number_format($averageRating, 1),
'reviewCount' => $reviewCount,
'bestRating' => '5',
'worstRating' => '1'
],
'review' => array_map(function($review) {
$reviewSchema = [
'@type' => 'Review',
'author' => [
'@type' => 'Person',
'name' => $review['author']
],
'reviewRating' => [
'@type' => 'Rating',
'ratingValue' => $review['ratingValue'] ?? 5,
'bestRating' => '5',
'worstRating' => '1'
],
'reviewBody' => $review['reviewBody']
];
// Add date if provided
if (isset($review['datePublished'])) {
$reviewSchema['datePublished'] = $review['datePublished'];
}
// Add job title/role if provided
if (isset($review['authorRole'])) {
$reviewSchema['author']['jobTitle'] = $review['authorRole'];
}
return $reviewSchema;
}, $reviews)
];
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Generate standalone AggregateRating schema (without individual reviews)
*/
function generateAggregateRatingSchema($itemName, $itemType, $ratingValue, $reviewCount, $itemUrl = null) {
$baseUrl = 'https://ukdataservices.co.uk';
$schema = [
'@context' => 'https://schema.org',
'@type' => $itemType,
'name' => $itemName,
'url' => $itemUrl ?? $baseUrl,
'aggregateRating' => [
'@type' => 'AggregateRating',
'ratingValue' => number_format($ratingValue, 1),
'reviewCount' => $reviewCount,
'bestRating' => '5',
'worstRating' => '1'
]
];
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Predefined testimonials for the homepage and service pages
*/
$siteTestimonials = [
[
'author' => 'James Mitchell',
'authorRole' => 'Retail Director, London Fashion Group',
'reviewBody' => 'UK Data Services transformed our competitor analysis process. Their web scraping accuracy and speed helped us make better pricing decisions. We\'ve seen a 23% improvement in our market positioning since working with them.',
'ratingValue' => 5,
'datePublished' => '2024-09-15'
],
[
'author' => 'Sarah Chen',
'authorRole' => 'Head of Strategy, City Fintech Ltd',
'reviewBody' => 'Outstanding data analytics service. They helped us understand our market position and identify opportunities we\'d completely missed. The team\'s expertise in financial data and GDPR compliance gave us complete confidence.',
'ratingValue' => 5,
'datePublished' => '2024-08-22'
],
[
'author' => 'Michael Thompson',
'authorRole' => 'Managing Partner, London Property Advisors',
'reviewBody' => 'Professional, GDPR-compliant, and incredibly responsive. Their property data extraction service has become essential to our London operations. The 99.8% accuracy rate they promised was actually exceeded in our experience.',
'ratingValue' => 5,
'datePublished' => '2024-07-10'
],
[
'author' => 'Emma Williams',
'authorRole' => 'CEO, Manchester Logistics Solutions',
'reviewBody' => 'Exceptional service quality. The data cleaning and validation work they did on our supply chain database saved us thousands in operational costs. Highly recommend for any Manchester business.',
'ratingValue' => 5,
'datePublished' => '2024-06-28'
],
[
'author' => 'David Brown',
'authorRole' => 'Director of Analytics, Birmingham Manufacturing Co',
'reviewBody' => 'We needed complex automotive parts pricing data across multiple European suppliers. UK Data Services delivered beyond expectations with excellent accuracy and compliance documentation.',
'ratingValue' => 5,
'datePublished' => '2024-05-15'
],
[
'author' => 'Laura Johnson',
'authorRole' => 'Marketing Director, Scottish Energy Corp',
'reviewBody' => 'Their competitive intelligence service gave us insights into market movements we couldn\'t have obtained otherwise. Professional team with deep technical expertise.',
'ratingValue' => 5,
'datePublished' => '2024-04-20'
]
];
/**
* Service-specific testimonials
*/
$serviceTestimonials = [
'web-scraping' => [
[
'author' => 'Robert Harris',
'authorRole' => 'CTO, E-commerce Solutions Ltd',
'reviewBody' => 'Their web scraping capabilities are world-class. They handled complex JavaScript-rendered pages with ease and delivered clean, accurate data exactly as specified.',
'ratingValue' => 5
]
],
'price-monitoring' => [
[
'author' => 'Sophie Turner',
'authorRole' => 'Pricing Manager, UK Retail Chain',
'reviewBody' => 'The price monitoring alerts have revolutionized how we respond to competitor pricing. We now react in hours instead of days.',
'ratingValue' => 5
]
],
'data-cleaning' => [
[
'author' => 'Mark Stevens',
'authorRole' => 'Data Manager, Healthcare Analytics',
'reviewBody' => 'They cleaned and standardized over 2 million patient records with 99.9% accuracy. The improvement in our data quality has been transformational.',
'ratingValue' => 5
]
]
];
// If $reviews is set, output the schema automatically
if (isset($reviews) && is_array($reviews)) {
echo generateReviewSchema(
$reviews,
$reviewItemName ?? 'UK Data Services',
$reviewItemType ?? 'Organization',
$reviewItemUrl ?? null
);
}

View File

@@ -1,223 +0,0 @@
<?php
/**
* Service Schema Component
* Generates Service structured data for improved SEO
*
* Usage:
* $serviceData = [
* 'name' => 'Web Scraping Services',
* 'description' => 'Professional web scraping services...',
* 'url' => 'https://ukdataservices.co.uk/services/web-scraping',
* 'serviceType' => 'Web Scraping',
* 'priceRange' => '500-50000',
* 'features' => ['Feature 1', 'Feature 2']
* ];
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/service-schema.php');
*/
/**
* Generate Service Schema JSON-LD
*
* @param string $serviceName The name of the service
* @param string $serviceDescription A detailed description of the service
* @param string $serviceUrl The canonical URL of the service page
* @param string $serviceType The type/category of service
* @param string|null $priceRange Optional price range (e.g., "500-50000")
* @param array $features Optional array of service features
* @return string JSON-LD script tag
*/
function generateServiceSchema($serviceName, $serviceDescription, $serviceUrl, $serviceType, $priceRange = null, $features = []) {
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Service',
'@id' => $serviceUrl . '#service',
'name' => $serviceName,
'description' => $serviceDescription,
'url' => $serviceUrl,
'serviceType' => $serviceType,
'provider' => [
'@type' => 'Organization',
'@id' => 'https://ukdataservices.co.uk/#organization',
'name' => 'UK Data Services',
'url' => 'https://ukdataservices.co.uk'
],
'areaServed' => [
'@type' => 'Country',
'name' => 'United Kingdom'
],
'availableChannel' => [
'@type' => 'ServiceChannel',
'serviceUrl' => 'https://ukdataservices.co.uk/quote',
'servicePhone' => '+44 1692 689150',
'availableLanguage' => 'English'
]
];
// Add price specification if provided
if ($priceRange) {
$prices = explode('-', $priceRange);
$schema['offers'] = [
'@type' => 'Offer',
'priceCurrency' => 'GBP',
'priceSpecification' => [
'@type' => 'PriceSpecification',
'minPrice' => (float)$prices[0],
'maxPrice' => isset($prices[1]) ? (float)$prices[1] : null,
'priceCurrency' => 'GBP'
],
'availability' => 'https://schema.org/InStock',
'validFrom' => date('Y-m-d')
];
}
// Add features/service output if provided
if (!empty($features)) {
$schema['hasOfferCatalog'] = [
'@type' => 'OfferCatalog',
'name' => $serviceName . ' Features',
'itemListElement' => array_map(function($feature) {
return [
'@type' => 'Offer',
'itemOffered' => [
'@type' => 'Service',
'name' => $feature
]
];
}, $features)
];
}
return '<script type="application/ld+json">' . "\n" .
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
'</script>';
}
/**
* Predefined service configurations for consistency
*/
$serviceConfigs = [
'web-scraping' => [
'name' => 'Web Scraping Services UK',
'description' => 'Professional web scraping and data extraction services for UK businesses. Automated data collection from websites with 99.8% accuracy and full GDPR compliance.',
'url' => 'https://ukdataservices.co.uk/services/web-scraping',
'serviceType' => 'Web Scraping',
'priceRange' => '500-50000',
'features' => [
'Automated data extraction',
'Real-time monitoring',
'GDPR-compliant collection',
'Custom API delivery',
'Multi-format output'
]
],
'competitive-intelligence' => [
'name' => 'Competitive Intelligence Services UK',
'description' => 'Strategic competitive intelligence and market analysis services. Monitor competitors, track market trends, and gain actionable business insights.',
'url' => 'https://ukdataservices.co.uk/services/competitive-intelligence',
'serviceType' => 'Competitive Intelligence',
'priceRange' => '1000-25000',
'features' => [
'Competitor monitoring',
'Market trend analysis',
'Price tracking',
'Product intelligence',
'Strategic reporting'
]
],
'price-monitoring' => [
'name' => 'Price Monitoring Services UK',
'description' => 'Real-time price monitoring and competitor price tracking services. E-commerce pricing intelligence for UK retailers and brands.',
'url' => 'https://ukdataservices.co.uk/services/price-monitoring',
'serviceType' => 'Price Monitoring',
'priceRange' => '500-15000',
'features' => [
'Real-time price tracking',
'Competitor price alerts',
'MAP monitoring',
'Historical price analysis',
'Automated reporting'
]
],
'data-cleaning' => [
'name' => 'Data Cleaning & Validation Services UK',
'description' => 'Professional data cleaning, validation, and standardisation services. Transform messy data into accurate, structured datasets.',
'url' => 'https://ukdataservices.co.uk/services/data-cleaning',
'serviceType' => 'Data Cleaning',
'priceRange' => '500-20000',
'features' => [
'Duplicate removal',
'Data standardisation',
'Format validation',
'Error correction',
'Quality assurance'
]
],
'data-analytics' => [
'name' => 'Data Analytics Services UK',
'description' => 'Business intelligence and data analytics solutions for UK enterprises. Transform raw data into actionable insights.',
'url' => 'https://ukdataservices.co.uk/services/data-analytics',
'serviceType' => 'Data Analytics',
'priceRange' => '1000-30000',
'features' => [
'Business intelligence',
'Predictive analytics',
'Custom dashboards',
'Data visualisation',
'Strategic insights'
]
],
'api-development' => [
'name' => 'API Development Services UK',
'description' => 'Custom API development and data integration services. Build robust APIs to connect your systems and automate data workflows.',
'url' => 'https://ukdataservices.co.uk/services/api-development',
'serviceType' => 'API Development',
'priceRange' => '2000-40000',
'features' => [
'Custom API design',
'System integration',
'Real-time data feeds',
'Authentication systems',
'Documentation'
]
],
'property-data-extraction' => [
'name' => 'UK Property Data Extraction Services',
'description' => 'Professional property data extraction from UK property portals including Rightmove, Zoopla, and OnTheMarket. GDPR-compliant property market intelligence.',
'url' => 'https://ukdataservices.co.uk/services/property-data-extraction',
'serviceType' => 'Property Data Extraction',
'priceRange' => '1000-25000',
'features' => [
'Property portal data extraction',
'Market analysis',
'Investment research data',
'Rental market intelligence',
'Commercial property data'
]
],
'financial-data-services' => [
'name' => 'Financial Data Services UK',
'description' => 'FCA-aware financial data services for hedge funds, asset managers, and investment firms. Market data extraction and alternative data solutions.',
'url' => 'https://ukdataservices.co.uk/services/financial-data-services',
'serviceType' => 'Financial Data Services',
'priceRange' => '5000-100000',
'features' => [
'Market data extraction',
'Alternative data feeds',
'Securities monitoring',
'Compliance-aware collection',
'API delivery'
]
]
];
// If $serviceData is set, output the schema automatically
if (isset($serviceData) && is_array($serviceData)) {
echo generateServiceSchema(
$serviceData['name'],
$serviceData['description'],
$serviceData['url'],
$serviceData['serviceType'],
$serviceData['priceRange'] ?? null,
$serviceData['features'] ?? []
);
}

View File

@@ -1,233 +0,0 @@
<?php
/**
* URL Configuration
* Centralized URL mapping for internal linking consistency
*
* Usage:
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/url-config.php');
* echo $urlMap['services']['web-scraping'];
*/
$baseUrl = 'https://ukdataservices.co.uk';
/**
* Complete URL map for the site
*/
$urlMap = [
'home' => '/',
'about' => '/about',
'quote' => '/quote',
'faq' => '/faq',
'blog' => '/blog',
'contact' => '/#contact',
'project-types' => '/project-types',
'case-studies' => '/case-studies',
// Services
'services' => [
'index' => '/#services',
'web-scraping' => '/services/web-scraping',
'competitive-intelligence' => '/services/competitive-intelligence',
'price-monitoring' => '/services/price-monitoring',
'data-cleaning' => '/services/data-cleaning',
'data-analytics' => '/services/data-analytics',
'api-development' => '/services/api-development',
'property-data-extraction' => '/services/property-data-extraction',
'financial-data-services' => '/services/financial-data-services'
],
// Locations
'locations' => [
'index' => '/locations',
'london' => '/locations/london',
'manchester' => '/locations/manchester',
'birmingham' => '/locations/birmingham',
'edinburgh' => '/locations/edinburgh',
'cardiff' => '/locations/cardiff'
],
// Blog categories
'blog-categories' => [
'web-scraping' => '/blog/categories/web-scraping',
'data-analytics' => '/blog/categories/data-analytics',
'business-intelligence' => '/blog/categories/business-intelligence',
'compliance' => '/blog/categories/compliance',
'industry-insights' => '/blog/categories/industry-insights',
'technology' => '/blog/categories/technology',
'case-studies' => '/blog/categories/case-studies'
],
// Legal pages
'legal' => [
'privacy-policy' => '/privacy-policy',
'terms-of-service' => '/terms-of-service',
'cookie-policy' => '/cookie-policy',
'gdpr-compliance' => '/gdpr-compliance'
]
];
/**
* Service metadata for internal linking and SEO
*/
$serviceData = [
'web-scraping' => [
'url' => '/services/web-scraping',
'title' => 'Web Scraping Services',
'shortTitle' => 'Web Scraping',
'description' => 'Professional web scraping and data extraction services',
'icon' => 'icon-web-scraping-v2.svg'
],
'competitive-intelligence' => [
'url' => '/services/competitive-intelligence',
'title' => 'Competitive Intelligence',
'shortTitle' => 'Competitive Intelligence',
'description' => 'Market analysis and competitor monitoring services',
'icon' => 'icon-analytics.svg'
],
'price-monitoring' => [
'url' => '/services/price-monitoring',
'title' => 'Price Monitoring',
'shortTitle' => 'Price Monitoring',
'description' => 'Real-time price tracking and competitor pricing alerts',
'icon' => 'icon-price-monitoring.svg'
],
'data-cleaning' => [
'url' => '/services/data-cleaning',
'title' => 'Data Cleaning & Validation',
'shortTitle' => 'Data Cleaning',
'description' => 'Professional data cleaning and quality assurance',
'icon' => 'icon-data-processing.svg'
],
'data-analytics' => [
'url' => '/services/data-analytics',
'title' => 'Data Analytics',
'shortTitle' => 'Analytics',
'description' => 'Business intelligence and data analytics solutions',
'icon' => 'icon-analytics.svg'
],
'api-development' => [
'url' => '/services/api-development',
'title' => 'API Development',
'shortTitle' => 'API Development',
'description' => 'Custom API development and system integration',
'icon' => 'icon-automation.svg'
],
'property-data-extraction' => [
'url' => '/services/property-data-extraction',
'title' => 'Property Data Extraction',
'shortTitle' => 'Property Data',
'description' => 'UK property market data from Rightmove, Zoopla, OnTheMarket',
'icon' => 'icon-property.svg'
],
'financial-data-services' => [
'url' => '/services/financial-data-services',
'title' => 'Financial Data Services',
'shortTitle' => 'Financial Data',
'description' => 'FCA-compliant financial and market data extraction',
'icon' => 'icon-financial.svg'
]
];
/**
* Location metadata for internal linking
*/
$locationData = [
'london' => [
'url' => '/locations/london',
'title' => 'London',
'region' => 'Greater London',
'description' => 'Web scraping and data analytics services in London'
],
'manchester' => [
'url' => '/locations/manchester',
'title' => 'Manchester',
'region' => 'Greater Manchester',
'description' => 'Data analytics and web scraping services in Manchester'
],
'birmingham' => [
'url' => '/locations/birmingham',
'title' => 'Birmingham',
'region' => 'West Midlands',
'description' => 'Data services and business intelligence in Birmingham'
],
'edinburgh' => [
'url' => '/locations/edinburgh',
'title' => 'Edinburgh',
'region' => 'Scotland',
'description' => 'Data analytics and web scraping services in Edinburgh'
],
'cardiff' => [
'url' => '/locations/cardiff',
'title' => 'Cardiff',
'region' => 'Wales',
'description' => 'Data services and business intelligence in Cardiff'
]
];
/**
* Related services mapping for cross-linking
*/
$relatedServices = [
'web-scraping' => ['competitive-intelligence', 'price-monitoring', 'data-cleaning'],
'competitive-intelligence' => ['web-scraping', 'price-monitoring', 'data-analytics'],
'price-monitoring' => ['web-scraping', 'competitive-intelligence', 'data-analytics'],
'data-cleaning' => ['web-scraping', 'data-analytics', 'api-development'],
'data-analytics' => ['competitive-intelligence', 'data-cleaning', 'api-development'],
'api-development' => ['web-scraping', 'data-cleaning', 'data-analytics'],
'property-data-extraction' => ['web-scraping', 'data-cleaning', 'competitive-intelligence'],
'financial-data-services' => ['web-scraping', 'data-analytics', 'api-development']
];
/**
* Get full URL with base URL
*
* @param string $path Relative path
* @return string Full URL
*/
function getFullUrl($path) {
global $baseUrl;
return $baseUrl . $path;
}
/**
* Get service URL by key
*
* @param string $serviceKey Service identifier
* @return string Service URL
*/
function getServiceUrl($serviceKey) {
global $urlMap;
return $urlMap['services'][$serviceKey] ?? '/#services';
}
/**
* Get location URL by key
*
* @param string $locationKey Location identifier
* @return string Location URL
*/
function getLocationUrl($locationKey) {
global $urlMap;
return $urlMap['locations'][$locationKey] ?? '/';
}
/**
* Get related services for a given service
*
* @param string $serviceKey Current service key
* @return array Array of related service data
*/
function getRelatedServices($serviceKey) {
global $relatedServices, $serviceData;
$related = $relatedServices[$serviceKey] ?? [];
$result = [];
foreach ($related as $relatedKey) {
if (isset($serviceData[$relatedKey])) {
$result[] = $serviceData[$relatedKey];
}
}
return $result;
}

View File

@@ -18,7 +18,7 @@ header('Content-Security-Policy: default-src \'self\'; script-src \'self\' \'uns
// SEO and performance optimizations // SEO and performance optimizations
$page_title = "Web Scraping Services UK | Get Your Free Quote Today"; $page_title = "Web Scraping Services UK | Get Your Free Quote Today";
$page_description = "GDPR-compliant web scraping & data analytics for UK businesses. 99.8% accuracy, competitive pricing data. Get your free quote today."; $page_description = "Custom web scraping &amp; data extraction for UK businesses. Competitor prices, property listings, market data — delivered clean, structured, on schedule. No contract. Free quote.";
$canonical_url = "https://ukdataservices.co.uk/"; $canonical_url = "https://ukdataservices.co.uk/";
$keywords = "web scraping services UK, data analytics London, web scraping UK, data extraction services, business intelligence, competitive analysis, price monitoring, data analytics Manchester, market research, web data mining, GDPR compliant scraping, enterprise data solutions, automated data collection UK"; $keywords = "web scraping services UK, data analytics London, web scraping UK, data extraction services, business intelligence, competitive analysis, price monitoring, data analytics Manchester, market research, web data mining, GDPR compliant scraping, enterprise data solutions, automated data collection UK";
$author = "UK Data Services"; $author = "UK Data Services";

View File

@@ -1,311 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
<!-- Blog Index -->
<url> <url>
<loc>https://ukdataservices.co.uk/blog/</loc> <loc>https://ukdataservices.co.uk/blog/articles/ai-powered-data-extraction</loc>
<lastmod>2025-08-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<!-- Blog Search -->
<url>
<loc>https://ukdataservices.co.uk/blog/search.php</loc>
<lastmod>2025-06-08</lastmod>
<changefreq>weekly</changefreq>
<priority>0.6</priority>
</url>
<!-- Blog Categories -->
<url>
<loc>https://ukdataservices.co.uk/blog/categories/web-scraping.php</loc>
<lastmod>2025-06-08</lastmod>
<changefreq>weekly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/categories/data-analytics.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/business-intelligence-consultants-uk-selection-guide</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/categories/business-intelligence.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/business-intelligence-dashboard-design</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/categories/compliance.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/cloud-native-scraping-architecture</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/categories/technology.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/competitive-intelligence-roi-metrics</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/categories/case-studies.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/competitor-price-monitoring-software-build-vs-buy-analysis</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/categories/industry-insights.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/data-analytics-companies-london-top-providers-compared</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>weekly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<!-- Blog Articles -->
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/web-scraping-compliance-uk-guide.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/data-automation-strategies-uk-businesses</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.9</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/ai-powered-data-extraction.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/data-protection-impact-assessments</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/business-intelligence-dashboard-design.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/data-quality-validation-pipelines</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/cloud-native-scraping-architecture.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/data-subject-rights-management</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/competitive-intelligence-roi-metrics.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/database-optimization-big-data</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/data-automation-strategies-uk-businesses.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/ecommerce-trends-uk-2025</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/data-protection-impact-assessments.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/financial-services-data-transformation</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/data-quality-validation-pipelines.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/fintech-market-analysis-uk</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/data-subject-rights-management.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/free-web-scraping-tools-launch</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/database-optimization-big-data.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/gdpr-data-minimisation-practices</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/ecommerce-trends-uk-2025.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/handling-captchas-scraping</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/financial-services-data-transformation.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/healthcare-research-data-collection</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/fintech-market-analysis-uk.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/international-data-transfers-uk</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/gdpr-data-minimisation-practices.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/javascript-heavy-sites-scraping</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/handling-captchas-scraping.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/kubernetes-scraping-deployment</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/healthcare-research-data-collection.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/manufacturing-data-transformation</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/international-data-transfers-uk.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/manufacturing-supply-chain-optimization</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/javascript-heavy-sites-scraping.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/media-content-aggregation-platform</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/kubernetes-scraping-deployment.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/predictive-analytics-customer-churn</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/manufacturing-data-transformation.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/property-data-aggregation-success</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/manufacturing-supply-chain-optimization.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/python-data-pipeline-tools-2025</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/media-content-aggregation-platform.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/python-scrapy-enterprise-guide</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/predictive-analytics-customer-churn.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/real-time-analytics-streaming-data</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/property-data-aggregation-success.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/real-time-analytics-streaming</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/python-data-pipeline-tools-2025.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/real-time-data-extraction-technical-guide-uk-businesses</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/python-scrapy-enterprise-guide.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/retail-competitor-monitoring-case</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/real-time-analytics-streaming-data.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/retail-price-monitoring-strategies</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/real-time-analytics-streaming.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/selenium-vs-playwright-comparison</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/retail-competitor-monitoring-case.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/sql-analytics-advanced-techniques</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/retail-price-monitoring-strategies.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/uk-cookie-law-compliance</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/selenium-vs-playwright-comparison.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/uk-property-market-data-trends</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/sql-analytics-advanced-techniques.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/web-scraping-compliance-uk-guide</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/uk-cookie-law-compliance.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/web-scraping-rate-limiting</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://ukdataservices.co.uk/blog/articles/uk-property-market-data-trends.php</loc> <loc>https://ukdataservices.co.uk/blog/articles/web-scraping-services-uk-complete-buyers-guide</loc>
<lastmod>2025-06-08</lastmod> <lastmod>2026-02-22</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.8</priority> <priority>0.7</priority>
</url> </url>
<url>
<loc>https://ukdataservices.co.uk/blog/articles/web-scraping-rate-limiting.php</loc>
<lastmod>2025-06-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<!-- New High-Priority Blog Posts -->
<url>
<loc>https://ukdataservices.co.uk/blog/articles/web-scraping-services-uk-complete-buyers-guide.php</loc>
<lastmod>2025-08-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://ukdataservices.co.uk/blog/articles/data-analytics-companies-london-top-providers-compared.php</loc>
<lastmod>2025-08-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://ukdataservices.co.uk/blog/articles/business-intelligence-consultants-uk-selection-guide.php</loc>
<lastmod>2025-08-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://ukdataservices.co.uk/blog/articles/competitor-price-monitoring-software-build-vs-buy-analysis.php</loc>
<lastmod>2025-08-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://ukdataservices.co.uk/blog/articles/real-time-data-extraction-technical-guide-uk-businesses.php</loc>
<lastmod>2025-08-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
</urlset> </urlset>