Blocking AI Scrapers: Protecting Your Content from Unauthorised Training Data
estimated read time: 6 minutes
Blocking AI Scrapers: Protecting Your Content from Unauthorised Training Data
This week I discovered something fascinating (and mildly infuriating) in my blog analytics: 68% of my "traffic" wasn't human readers — it was AI scrapers. OpenAI's GPTBot, Meta's scraper, ChatGPT-User, and a parade of other bots were harvesting my technical writing to train models that would then regurgitate my work without attribution.
Here's how I figured it out, why it matters, and how I'm blocking them.
The Discovery
I was looking at Loki logs for my blog's post_read events this week (2026-05-26 onwards) and noticed something odd:
- Direct traffic: 87.8% (no referrer)
- Search engines: Under 2%
That direct traffic percentage was suspiciously high. Most blogs see 30-50% direct at best. So I dug into the user agents:
LOKI="http://loki.example.com"
curl -G "$LOKI/loki/api/v1/query_range" \
-H "X-Scope-OrgID: fake" \
--data-urlencode 'query={namespace="production"} |= "post_read"' \
| python3 -c "import json, sys; ..."
The Results
Known AI scrapers: 47% of traffic
- Meta's scraper: largest share (link preview generation for WhatsApp/Facebook)
- ChatGPT/GPTBot: significant portion (OpenAI training scrapers)
- AhrefsBot: SEO crawler
- YandexBot: smaller share
Suspected bot farms: 21% of traffic
- Ancient Chrome versions (Chrome 41, 78, 85 — no human runs these in 2026)
- iOS 13 devices (released 2019, long obsolete)
Actual human readers: 32% of traffic
So my "trending posts"? The view counts were inflated by roughly 3x due to bot traffic.
Why This Matters
The Plagiaris… I Mean "Training Data" Problem
When OpenAI's GPTBot scrapes your blog, it's harvesting your content for model training. Later, someone asks ChatGPT "how do I set up Longhorn on k3s?" and it regurgitates a summary of your guide — without attribution, without a link, without credit.
You spent hours writing that guide. OpenAI makes billions from a model trained on your work. You get nothing.
It's Not Just OpenAI
- Anthropic (ClaudeBot) — doing the same thing
- Google (Google-Extended) — separate from Googlebot, specifically for Bard/Gemini training
- Meta (meta-externalagent) — link previews are fine, but they also train LLMs
- Cohere, Perplexity, Bytespider (TikTok), Diffbot — all harvesting content
The "But It's Public!" Argument
Yes, my blog is public. That doesn't make it public domain. Copyright exists. Just because I publish something openly doesn't mean companies have the right to commercialise derivatives without permission.
If I write a book and put it in a public library, that doesn't mean anyone can photocopy it, repackage it, and sell it.
The Solution: Blocking AI Scrapers
I'm implementing three layers of defence:
1. robots.txt (Polite Request)
Most scrapers honour robots.txt. Some don't. But it's the baseline:
# Blocking AI Scrapers
User-agent: GPTBot
Disallow: /
User-agent: ChatGPT-User
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: anthropic-ai
Disallow: /
User-agent: ClaudeBot
Disallow: /
User-agent: Google-Extended
Disallow: /
User-agent: cohere-ai
Disallow: /
User-agent: PerplexityBot
Disallow: /
User-agent: Bytespider
Disallow: /
# Allow legitimate search engines
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
Note the distinction: Googlebot (search indexing) is allowed. Google-Extended (AI training) is blocked.
2. HTML Meta Tags
Next.js supports robots meta tags in the layout:
export const metadata: Metadata = {
// ...
robots: {
index: true,
follow: true,
},
other: {
robots: "noai, noimageai",
},
};
This tells crawlers "index me for search, but don't train AI models on me."
3. Traefik Middleware (HTTP Header)
For defence in depth, I'm adding an X-Robots-Tag HTTP header via Traefik middleware in my k3s cluster:
Helm chart: infra/templates/middleware.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: block-ai-scrapers
spec:
headers:
customResponseHeaders:
X-Robots-Tag: "noai, noimageai"
Reference it in the Ingress: infra/values.yaml
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.middlewares: "production-blog-block-ai-scrapers@kubernetescrd"
This sends the header on every response, even for dynamically-generated pages where meta tags might be missed.
4. (Optional) User-Agent Filtering
If you want to be more aggressive, you can block scrapers at the ingress level:
# In Traefik IngressRoute or nginx config
if ($http_user_agent ~\* (GPTBot|ChatGPT-User|ClaudeBot)) {
return 403;
}
I'm not doing this yet — I want to monitor whether the polite blocks work first.
Testing the Implementation
After deploying, you can verify the headers:
curl -I https://blog.foulkes.cloud
# Should see:
# X-Robots-Tag: noai, noimageai
And check that robots.txt is accessible:
curl https://blog.foulkes.cloud/robots.txt
The Helm Chart Changes
For those running Next.js on k3s via Helm (like I am), here's the full changeset:
Branch: feat/block-ai-scrapers
Files changed:
my-blog/public/robots.txt(new)my-blog/src/app/layout.tsx(add noai meta tags)infra/templates/middleware.yaml(new Traefik middleware)infra/values.yaml(enable middleware, list blocked scrapers)
Full diff: github.com/dfoulkes/personal-blog/pull/XXX (TODO: update with PR number)
Will This Actually Work?
For well-behaved scrapers: Yes. OpenAI, Anthropic, Google, and others have all stated they honour robots.txt and noai directives.
For bad actors: No. Some scrapers ignore robots.txt entirely. If they become a problem, you need user-agent filtering or a WAF (Web Application Firewall).
Can they still scrape my content? Technically yes — if they ignore robots.txt and fake their user-agent, there's nothing stopping them short of IP blocking or CAPTCHAs (which hurt legitimate users).
But making it harder and explicitly stating you don't consent strengthens your legal position if it ever comes to that.
The Bigger Picture
This isn't just about my blog. It's about the web as a commons.
If every technical blog gets scraped, summarised, and regurgitated by AI chatbots — who will write the blogs? Why would I spend hours documenting how to configure Longhorn backups to MinIO if ChatGPT just steals it and serves it up without sending readers my way?
AI companies are training on the outputs of human expertise and then replacing the humans. That's a death spiral for the open web.
So block the scrapers. Make them ask permission. Force them to compensate creators. Or at least make them acknowledge that "training data" isn't some abstract digital resource — it's someone's work.
Resources
- OpenAI's GPTBot docs: https://platform.openai.com/docs/gptbot
- Google's crawler docs: https://developers.google.com/search/docs/crawling-indexing/overview-google-crawlers
- Anthropic's robots.txt policy: https://support.anthropic.com/en/articles/8896518-does-claude-crawl-websites
- Full bot list (Dark Visitors): https://darkvisitors.com/
Update Log
- 2026-05-30: Initial implementation — robots.txt, meta tags, Traefik middleware deployed
- (I'll update this post as I track whether the blocks actually work)
If you found this useful, consider starring the personal-blog repo or sharing this post. With humans. Not bots.
Related Articles
My AI Wrote a Keylogger Into My Keyboard Driver. Another AI Caught It.
While building a Rust driver for my Razer keyboard, the AI I was working with wrote a udev rule that let any program I ran read my keystrokes, underneath Wayland. It even told me it was safe. A second AI caught it past midnight. How it happened, how I proved it, why the first fix didn't work, and a script to check your own machine.
Automating Cloudflare DNS Updates from a Kubernetes CronJob
When my ISP started rotating my residential IP weekly, I stopped updating Cloudflare manually and built a Kubernetes CronJob that does it automatically every 15 minutes.
k3s HA on Raspberry Pi: Zero-Downtime Cluster in 45 Minutes (Multi-Master + MySQL)
Stop single-point failures. Build a production-grade k3s cluster with 3 master nodes, external MySQL, and load balancing—all on budget Pi hardware. Step-by-step guide with troubleshooting.
I Built a Council of AIs That Live in My Kubernetes Cluster
How I built a council of specialist AI models running on AWS Bedrock inside Kubernetes — fanning questions out in parallel and deliberating for a verdict.