Watermarks & Anti-Scraping in Practice: Defending Your Content, Images, and APIs
Bots scraping your content, images, and product data around the clock? From Cloudflare's four-layer detection and JA3/JA4 fingerprints to signed URLs, watermark forensics, and an ROI checklist — a costed anti-scraping playbook for small site owners.

Three boundaries first, so this doesn't collide with guides already on the site — and so you don't finish reading and realize "this wasn't what I needed."
This guide does not cover defending against hackers: CSP, security headers, CSRF, and dependency vulnerabilities belong to the site's Web Security Baseline Guide (vibe-project-web-security-baseline-guide). It does not cover payment fraud or promo abuse: fake humans placing real orders and coupons being harvested by machines are the "people" problem solved by the Fraud Prevention Guide (vibe-project-fraud-prevention-guide). It does not cover moderating what your users post: detecting porn, spam, and abuse is the territory of the Content Moderation Guide (vibe-project-content-moderation-guide).
This guide answers a different anxiety site owners have: my public content, images, and product data are being scraped around the clock by bots — what do I do? Scrapers don't hack your server or steal from your payment flow; they just carry away, page by page, what you worked hard to produce — to train models, to undercut you on price comparison, to mirror your entire site. From edge-layer detection, content-layer watermarking, and resource-layer hotlink protection, to cost control after the bots arrive and the legal waterline, everything here is about "protecting my assets," not "blocking my attackers." The whole piece is written from the defender's side: you will find no techniques here for bypassing anyone's WAF, CAPTCHA, or anti-scraping systems.
One prior conclusion, up front: there is no silver bullet in anti-scraping, only cost exchange. Every dollar and every config line you spend raises the scraper's cost of collection; once scraping costs more than the content is worth, the bot moves on to a cheaper target. So this guide's destination isn't "zero bots" — it's an ROI checklist: what the free tier gets you, what $20–200/month buys, what's Enterprise-only, and when "do nothing" is actually the optimal move.
1. The four layers of modern bot detection: User-Agent dies at the handshake
A decade ago, anti-scraping was a User-Agent blacklist game: see python-requests, block it; the scraper rotates its UA and walks around you, and both sides duel inside HTTP headers. That era is long over. Using Cloudflare's documented detection stack as the reference, modern anti-bot is a four-layer funnel, and every request passes through it top to bottom — each layer answering a different question:

Layer 1 · Network: where are you coming from. IP reputation databases, ASN (autonomous system number), datacenter IP ranges. Datacenter IPs (AWS, Alibaba Cloud, proxy providers' ASNs) are suspicious by default; residential IPs look cleaner. This layer is the cheapest — it's a table lookup, no decryption, no scripts. It's also the crudest: a scraper that rotates through a residential proxy pool partially walks around it, so it's only the first sieve.
Layer 2 · TLS handshake: what is your "accent." This is the real watershed of anti-scraping. Before a client sends its first HTTP byte, it must complete the TLS handshake, and the ClientHello carries the cipher-suite list, extension list, and ALPN negotiation order — like a person's accent. The OpenSSL default handshake of Python requests sounds nothing like Chrome's BoringSSL handshake. The server computes a TLS fingerprint from it (JA3/JA4, detailed in the next section), and a request faking its User-Agent is exposed at the handshake stage: the UA claims to be Chrome while the fingerprint says Python, and that mismatch is itself the strongest bot signal.
Layer 3 · Protocol: are you speaking correctly. HTTP/2 SETTINGS frame parameters, header order and casing (the JA4H fingerprint covers exactly this layer), TCP window sizes. Real browsers send headers in a fixed order (Chrome always puts :method, :authority, :scheme, :path first), while scripting libraries tend to send them in their own dictionary order. Right headers in the wrong order still gives you away.
Layer 4 · Behavior: do you act human. JavaScript challenges (computations only a real browser can run), mouse trajectories and dwell time, request rate and path patterns, Cloudflare's bot score (1–99; below 30 is typically machine traffic). This layer is the most accurate — and the most expensive: it needs scripts, models, and continuous observation.
Why does understanding these four layers matter? Two direct engineering conclusions: first, stop spending budget on UA blacklists — that's a 2015 playbook; second, configure defenses layer by layer — on the free tier you only get layer 1 plus a bit of layer 4 (Bot Fight Mode); TLS-fingerprint-grade rules cost money (pricing in section 3). Knowing what each layer sells for keeps vendor demo pages from misleading you.
2. What the free tier gets you: do the no-cost things properly first
The most common mistake small site owners make is inverted: either assuming "free means useless" and skipping it, or assuming one toggle solves everything. The free tier has three weapons, each with a clear boundary of effectiveness.
Weapon 1: robots.txt — it only governs well-behaved crawlers. Its boundary must be stated once and clearly: robots.txt is a gentlemen's agreement, effective only against crawlers that honor it. Googlebot and Bingbot will read it; malicious scrapers never open the file and just start grabbing. So the correct use of robots.txt is "declaring intent + traffic shaping," not "defense":
User-agent: GPTBot
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: *
Disallow: /admin/
Disallow: /api/internal/
This says: OpenAI's training crawler GPTBot and Common Crawl's CCBot should stay off the whole site, while admin and internal API paths are closed to all crawlers. Verify it in the search engines' webmaster tools afterward. Against crawlers that don't play by the rules, robots.txt does exactly zero — that's when you need edge-layer blocking (sections 3–4), not more Disallow lines in this file.
Weapon 2: Cloudflare Bot Fight Mode — a toggle on the free plan. Turn it on under Security → Bots in the Cloudflare dashboard; available on all plans including Free. It automatically challenges requests matching known bot signatures with zero rule-writing on your part. Position it accurately: it's "baseline protection" that stops low-end scripts and known-bad bots, not a serious adversary doing fingerprint spoofing. On the free plan it can't be bypassed or skipped with WAF custom rules — you either leave it on and accept false positives (it may challenge legitimate automation like your monitoring service or payment webhooks), or turn it off. Pro ($20/month) and up upgrade to Super Bot Fight Mode, which lets you set allow/challenge/block per bot category and extends protection to static resources.
Weapon 3: Cloudflare's one-click AI crawler blocking + X-Robots-Tag — built for "training scraping." Since 2024, AI training crawlers (GPTBot, ClaudeBot, CCBot, Bytespider, and friends) have become a new bleeding point for site owners. Cloudflare offers a one-click toggle under Security → Bots that blocks known AI scrapers and crawlers, on all plans including free, with Cloudflare maintaining the fingerprint list; since September 2026, newly onboarded domains block Training and Agent crawlers by default (on ad-supported pages), while Search indexing crawlers are unaffected. Note the distinction: training crawlers and search crawlers are two different crowds — blocking GPTBot doesn't affect your citations in ChatGPT search (that's OAI-SearchBot's job), and blocking Google-Extended doesn't affect your Google search rankings.
What about X-Robots-Tag: noindex? Its effect is routinely overestimated: noindex tells search engines "don't put this page in the index" (and kills cached snapshots in results), but it doesn't stop fetching at all — a crawler can still download your full text; it just can't appear in search results. To stop training scraping, use the CDN-layer AI crawler toggle above; noindex solves "don't appear in search results," a different problem. Don't mix the two.
Free-tier trio, summarized: robots.txt declares intent, Bot Fight Mode stops low-end scripts, the AI crawler toggle stops training scrapers. Thirty minutes of work total, blocking 80% of opportunistic scrapers. The remaining 20% are professionals — that's what the paid tiers are for.
3. TLS fingerprinting in practice: JA3, JA4, and Cloudflare's scraping-detection rules
This is the most technically dense section — and the "where does the money go" section. First, the lineage of the two fingerprint standards, because it comes up in interviews and architecture reviews with high probability.
JA3: the TLS fingerprint pioneer, open-sourced by Salesforce in 2017. The idea is blunt: concatenate the TLS version, cipher-suite list, extension list, and elliptic curves from the ClientHello in a fixed format, hash it with MD5, and get a 32-character hex string (e.g. cd08e31494f9531f560d64c695473da). The same HTTP client library produces the same handshake every time, so the fingerprint is stable and recognizable. It has two structural flaws: first, MD5 is an opaque hash — you can't tell whether two fingerprints are "similar"; second, the GREASE mechanism makes it unstable — Chrome inserts random dummy extensions into handshakes (GREASE: Generate Random Extensions And Sustain Extensibility, meant to stop middleboxes from ossifying), so the same Chrome produces a different JA3 on every connection. Fastly measured in 2023 that the canonical pre-Chrome-110 JA3 collapsed into a long tail after the Chrome 110 rollout. On May 1, 2025, Salesforce archived the JA3 GitHub repository, with the README pointing at FoxIO's JA4 as the maintained successor.
JA4: the successor, released by FoxIO in September 2023 (founder John Althouse is JA3's original author, who founded FoxIO after leaving Salesforce). It's not just a different hash over the same fields — the shape of the identifier changed:
- Human-readable prefix: a fingerprint like
t13d1516h2_8daaf6152771_e5627efa2ab1reads directly — t = TLS over TCP, 13 = TLS 1.3, d = SNI domain present, 15 = 15 cipher suites, 16 = 16 extensions, h2 = HTTP/2 negotiated via ALPN. You know roughly what client you're looking at without a lookup table. - Sorted-then-hashed, GREASE-aware: cipher and extension lists are sorted before SHA256 (truncated to 12 chars), and GREASE dummy values are stripped before counting. Order jitter and random dummies no longer change the fingerprint — the fix for JA3's most painful flaw.
- A whole fingerprint family: JA4 (TLS ClientHello), JA4S (ServerHello), JA4H (HTTP layer: method, version, header names and order), JA4T (TCP layer), JA4SSH, JA4Q (QUIC/HTTP3). JA4H maps directly onto layer 3 protocol detection from the previous section — header order is itself a fingerprint.
How to use it in practice? Cloudflare's official docs provide a set of "scraping detections" — behavioral detection IDs designed to catch volumetric scraping at the zone level:
50331648: observes request patterns dynamically analyzed by ASN, identifying anomalous scraping behavior;50331649: observes request patterns dynamically analyzed by JA4 fingerprint, identifying anomalous scraping behavior.
In the Cloudflare dashboard, go to Security → Security rules → Create rule → Custom rule, and write a custom rule with Bot Detection IDs (the official docs' example):
(any(cf.bot_management.detection_ids[*] in {50331648 50331649}) and not cf.bot_management.verified_bot)
This reads: if any scraping detection ID fires and the request is not a verified legitimate crawler (search engines) → take action (start with Managed Challenge, watch the false-positive rate, then tighten to Block). The not cf.bot_management.verified_bot half is critical: it keeps Googlebot and friends unaffected, so your SEO doesn't take a hit.
Budget warning (required reading): Cloudflare's bot scoring comes in three tiers with starkly different prices — the free plan's Bot Fight Mode is just an on/off switch with no fine control; Pro ($20/month) and up get Super Bot Fight Mode with per-category actions; the granular bot score (1–99, usable in custom rules as threshold expressions like cf.bot_management.score lt 30) is an Enterprise-only Bot Management add-on, quote-priced with no public list price. Which plans can use the detection_ids rule above depends on the bot-management capabilities entitled on your zone — when budgeting, don't let a demo page's score-threshold examples mislead you into thinking the $200/month Business plan can do it all. The Business plan ($200/month) only gets Super Bot Fight Mode, not the granular 1–99 bot score. That sentence deserves its own paragraph, because it's where small site owners most easily waste money in this section.
4. Behavioral rate limiting and challenges: three quotas for login pages, search pages, and APIs
The algorithm details (token bucket, sliding window, GCRA) are already covered in depth by the site's Rate Limiting Guide (vibe-project-rate-limiting-guide). This section only covers "how to configure it against scrapers" — a different question: the rate-limiting guide is "how to limit," this section is "whom to limit, and how hard."
Core principle: tier by path, grade by identity. Don't apply one threshold site-wide. In practice, use at least three tiers:
- Login / signup / password-reset pages: strictest. Per-IP limiting (e.g. 5 attempts per minute per IP) plus Turnstile (below). This fights credential stuffing and mass registration rather than scraping, but the quota thinking is the same — the highest-value entrances get the tightest cages.
- Search, listing, and filter pages: medium-strict. These are scrapers' favorites: one search endpoint can disgorge the whole catalog, one page parameter can walk the entire directory. Limit by IP + ASN combination, with thresholds at 3–5× normal human browsing speed (e.g. 60 search requests per minute per IP). Over the threshold, don't ban the IP outright — serve a JS challenge first. Real humans click through; scripts die on the spot.
- Public APIs: quota by key or IP. Anonymous unauthenticated calls get a tiny free allowance (e.g. 100/day); logged-in users get wider quotas per plan. Use a "fingerprint + IP" composite key for API limits — a lone IP is easily diluted by proxy pools.
Picking among Turnstile's three modes (Cloudflare's free CAPTCHA replacement, which works even if your DNS isn't proxied through Cloudflare): Managed (default, recommended: Cloudflare decides per-request whether to show a checkbox; most real visitors pass invisibly), Non-interactive (shows a small loading widget, never asks the visitor to click anything), Invisible (fully hidden, runs silently in the background). Guidance: login/signup forms get Managed — suspicious traffic is asked to tick a checkbox; low-friction surfaces like comment and contact forms get Non-interactive; background verification gets Invisible. Note that Turnstile returns only a pass/fail boolean, not a 0–1 risk score like reCAPTCHA v3 — if you want scores for graded handling, that's Enterprise Bot Management territory (see the pricing warning in section 3).
One often-overlooked point: the rate-limit response is itself information. Returning 429 with a Retry-After header is standard, but don't tell the scraper in the response body which rule fired and what the threshold is — that's handing them the blueprint of the cage.
5. Content watermarks: visible marks deter gentlemen, invisible marks build evidence
Watermarks come in two completely different species. Know which adversary you're deterring before you buy.
Species one: frontend dynamic watermarking — stops "insider screenshots," not scrapers. The implementation is blunt: a fixed-position Canvas or DOM overlay tiling semi-transparent "username + timestamp" text across the page, so any screenshot carries the leaker's identity. A dozen lines of code; the keys are generating the watermark content dynamically (username from the login session, timestamp to the minute) and resisting trivial DOM removal (a MutationObserver that redraws the watermark if its node is deleted, and logs the event). Its threat model is "a paying user screenshotting content outward" — it's useless against scrapers, which grab the DOM and API data and never "look" at the screen. Don't expect it to stop scraping; it stops people.
Species two: invisible image watermarks — for post-incident forensics, not pre-incident blocking. Two engineering routes: LSB steganography is simplest, hiding watermark bits in pixels' least significant bits, invisible to the eye — but one JPEG recompression destroys it, so it fits original-distribution scenarios; DCT-domain watermarking embeds the signal in mid-frequency coefficients of JPEG compression, surviving a degree of recompression, cropping, and transcoding, at the cost of a more complex pipeline step. The key insight: invisible watermarks answer "where did this image leak from," not "don't let anyone download this image." They're one link in the legal evidence chain (section 9), not an interception mechanism. Expecting a watermark to "prevent downloads" is like expecting an anti-theft tag to "prevent entry" — wrong tool for the job.
Watermarks on AI-generated content (one-sentence boundary): C2PA Content Credentials attach verifiable metadata to images/video stating who generated them and who edited them (pushed by Adobe, Sony, and other camera makers); SynthID is Google DeepMind's machine-readable watermark for AI-generated text, images, audio, and video. Both are "declare the source" mechanisms, and neither stops a determined adversary from stripping metadata — know they exist and where they apply; not worth engineering investment for a small site.
6. Image and static-asset hotlink protection: signed URLs and the truth about Referer
Image hotlink protection solves two problems: others hotlinking your image bandwidth, and scrapers bulk-downloading your originals. Do the math first: if your product images average 200KB and a scraper grabs 100,000 a day, that's 20GB of egress — real money on metered object storage like S3/R2. Hotlinking is worse: someone else's site embeds your images, and every visit to their page costs you CDN egress while they keep the conversion.
Signed URLs: put an expiry on every image URL. The server HMAC-signs "path + expiry timestamp" with a secret key; the URL carries the signature and expiry, and the CDN/object storage only serves it if verification passes. S3 and Cloudflare R2 natively support presigned URLs; Cloudinary has signed URLs too. The expiry policy is the key engineering decision: for images embedded in pages, set expiry to minutes or hours — the server signs URLs at page-render time, normal browsing is unaffected, and a scraper that stockpiles URLs finds them all dead the next day. Pair it with "don't let search engines cache original direct links" (Disallow the originals directory in robots.txt, or use X-Robots-Tag: noimageindex), or Google Image Search's cache becomes a permanent backdoor.
Referer/Origin whitelisting: stops gentlemen, not villains. Configuring your CDN to serve images only to requests with your own domain's Referer blocks ~90% of hotlinking — because hotlinkers are lazy and won't bother forging Referers. But its nature must be stated plainly: Referer is a request header the client fills in arbitrarily; one curl command forges it. Against professional scrapers, it's nothing. So Referer whitelisting is positioned as "cheap hotlink blocking"; bulk-download defense still needs signed URLs. Stack the two; they don't substitute for each other.
One more cheap-but-effective move: multi-size image distribution. Listing pages serve only 400px thumbnails, detail pages 1200px, and originals only on explicit "view original" clicks (which may require login). Even if a scraper grabs every image on the site, it gets thumbnails — the commercial value collapses, while your real users notice nothing.
7. API-layer anti-scraping: signatures, complexity limits, and SSR data exposure
Many vibe projects run naked APIs: whatever endpoints the frontend calls, scrapers call too, with parameters trivially reverse-engineered. API-layer defense does four things.
1. Private API signing: HMAC(timestamp + nonce) against replay. When your mobile app or first-party frontend calls sensitive endpoints, each request carries three headers: X-Timestamp (current timestamp), X-Nonce (random string), X-Signature = HMAC_SHA256(secret, timestamp + nonce + request path + request-body hash). The server verifies three things: the signature is valid (anti-tamper), the timestamp is within a ±5-minute window (anti-stale-replay), and the nonce hasn't appeared in Redis before (TTL twice the window, anti-in-window-replay). Don't hardcode the secret in frontend JS — frontend code is public, so a secret there is no secret. For web, the correct pattern is: the secret lives only on the server, the frontend exchanges its login session for a short-lived token, and signing happens server-side or via cookie sessions. Know the threat model: API signing stops "script kiddies copying your endpoints," not professionals who reverse your app — but it keeps 90% of opportunistic scrapers out.
2. GraphQL query depth and complexity limits. GraphQL's self-describing nature is a scraper's paradise: one introspection query reveals the entire schema. First job in production: disable introspection. Second: cap query depth (e.g. max 7 nesting levels) and compute complexity (assign each field a cost score, set a per-query budget, reject over-budget queries outright). Skip these two and a single 20-level nested query can flatten your database — this isn't just anti-scraping, it's anti-self-destruction.
3. Converging SSR data exposure like __NEXT_DATA__. Next.js embeds a __NEXT_DATA__ script tag in the HTML, stuffing server-computed props in as plaintext JSON for hydration. Scrapers don't even need your API — a regex over that JSON yields structured whole-site data. Converge it: filter sensitive fields (cost prices, supplier info, unpublished data) inside getServerSideProps — don't rely on the frontend "not rendering" them. Every byte that enters __NEXT_DATA__ is public. The thorough fix is making sensitive blocks client-fetched on demand (only after login) or moving to React Server Components so sensitive data never leaves the server.
4. Degraded responses for sensitive fields to unauthenticated scrapers. An extremely high-ROI move: unauthenticated requests see "public price cached for 1 hour" and stock as two buckets ("in stock / sold out") instead of exact numbers; logged-in users see real-time prices and exact inventory. Scrapers always get delayed, fuzzy data — a price-comparison bot holding 1-hour-stale prices has zero commercial value — while your real (logged-in) users notice nothing. Implementation cost: one "is logged in" branch.
8. Scraper cost control: the emergency switch for when you get scraped hard
Face reality: any defense can be scraped through one day — a new bot with a fresh fingerprint, or your Product Hunt launch getting "studied" by the whole internet. This section isn't "how to stop it" but "how to lose less money and recover fast when it happens."
First, identify "high-cost, low-value" paths. Not all scraping losses are equal: a scraped article page costs one CDN hit (fractions of a cent); scraped search pages, filter combinations, and export endpoints cost a database round-trip per hit — two orders of magnitude more. Fix: cache these three path types separately (cache search results 5–10 minutes; bots and humans see the same cached copy, and the consistency loss is acceptable) or degrade them (search requests from suspected bots return "showing top 20, log in for more"). Protect the database first; worry about experience second.
Watch CDN cache hit rates for bot traffic and human traffic separately. Many owners look at a 95% site-wide hit rate and think everything's fine — when the reality is "humans 99%, bots 40%" averaged together. Split by User-Agent or bot verdict in your CDN analytics; once a traffic class shows an abnormally high origin-fetch rate, bots are walking your dynamic paths page by page. That's when you reach for section 3's detection_ids rules and section 4's per-path limiting.
Keep an "emergency switch" checklist written down in the team wiki. At 3 a.m. during a scraping storm, you don't want to be reading docs:
- Cloudflare WAF one-click rule: under Security → Security rules, pre-write a rule that challenges all requests hitting
cf.bot_management.detection_ids50331648/50331649. Keep it on Log (record-only) normally; flip to Managed Challenge in an emergency — effective within a minute; - Origin rate limiting: Nginx
limit_reqor an app-level global degradation switch that temporarily cuts anonymous API quotas to 1/10th; - Kill export/bulk endpoints: one feature flag to shut down CSV export and bulk query APIs — convenient for users in peacetime, bleeding wounds in wartime;
- Notify: post "emergency mode engaged" in the team channel with a timestamp, for the postmortem.
Drill the switch list once while calm, confirming each item truly takes effect within 5 minutes. An emergency plan that's never been drilled is no plan.
9. The legal and compliance waterline: what technology can't stop, terms and takedowns cover
Technical defenses always leak; law is the second line — not a scarecrow, but genuinely usable. Three waterlines:
Waterline 1: ban bulk scraping explicitly in your ToS. Four drafting points: define "automated access" precisely (including crawlers, bulk downloading, and AI training scraping); require "prior written consent" for the above; reserve your rights to rate-limit, IP-ban, and terminate service; and scope data usage (e.g. "not for training machine-learning models" — a clause worth its own line in the AI-crawler era). Have a lawyer review it; a template clause's courtroom weight depends on wording, so don't improvise.
Waterline 2: the legal difference between robots.txt and ToS (one sentence). robots.txt is a technical-layer courtesy request with no contractual force; ToS are contract terms the visitor agrees to by using the service — violating them gets you cease-and-desist letters, bans, and lawsuits. One says "please don't enter," the other says "entering is breach." That's why section 2 has you write robots.txt as "declaring intent" — the real teeth are in the ToS.
Waterline 3: DMCA takedowns — for "scraped and republished." Note DMCA's scope: it covers "the other party republishing your copyrighted content" (mirror sites, pirate aggregators, your articles pasted verbatim onto their site) — then you can send a takedown notice to their host or search engine, and hosts usually act within 48 hours. It does not cover "they scraped your data for their own use" (training models, internal price comparison) — that's ToS breach and unfair competition, handled via lawyer letters and litigation. Keep the two scenarios apart; don't file DMCA complaints against training scraping — they'll be rejected.
Restating the defender's iron rule: this guide provides no techniques for bypassing anyone's WAF, CAPTCHA, or anti-scraping systems. Studying how the other side's technology works is for defense, not offense — every section here is "as a site owner, how do I protect myself." To evaluate your own defenses, use your own staging environment or hire a qualified security firm for authorized testing.
10. The small-site owner's ROI checklist: how to spend from free to Enterprise
The previous nine sections are the armory; this section is the shopping list. Three budget tiers, each stating what to buy and what not to buy.
Tier 1: free ($0, half a day of work). Cloudflare free plan + Bot Fight Mode toggle + one-click AI crawler blocking + robots.txt declaration + image signed URLs (native to R2/S3, no extra charge) + Referer whitelisting against hotlinking + degraded price/inventory for logged-out users. This combo stops 80% of opportunistic scrapers and 100% of bandwidth-stealing hotlinks — the best ROI on the field. Most content sites and indie shops under 100k monthly active users never need more than this tier.
Tier 2: $20–200/month (Pro/Business). Upgrade only when the free tier demonstrably fails — your logs show high-frequency scraping from fixed JA4 fingerprints, your search endpoints being walked. What you're buying: Super Bot Fight Mode (per-category bot handling, static-resource protection) + WAF custom rules (section 3's detection_ids scraping rules, fine-grained per-path rate limits) + longer log retention (for analyzing bot patterns). What not to buy: don't buy Business because you "want bot-score thresholds" — the $200/month Business plan has no granular 1–99 bot score; that's Enterprise-only (see section 3). Paying for a feature that doesn't exist is the one expense this section most wants to save you.
Tier 3: Enterprise (quote-based). Only three kinds of owners need this tier: your content is the core asset (image libraries, data APIs, paid research), where one scraping incident costs far more than the defense; you're facing professional scraping teams (residential proxy pools + real browsers + behavior simulation) that the first two tiers have proven unable to stop; or compliance requires complete bot audit logs. What you're buying: full Bot Management (1–99 bot scores, custom threshold rules, JavaScript-injection detection), AI Labyrinth (a honeypot feeding synthetic data to AI scrapers), dedicated tuning. Note: Enterprise is an annual contract, not a "try it for a month" thing — before signing, confirm your content is truly worth the price.
When to do nothing: the criteria. An anti-scraping guide ending with when not to anti-scrape isn't defeatism — it's accounting:
- Your content has no commercial moat (a public blog, a personal portfolio): what scrapers take is "citations," what they bring is backlinks and traffic — not fighting may earn more than fighting;
- You're in cold start: search-engine crawlers and AI search crawlers are your only traffic source, and aggressive blocking cuts your own lifeline — this is where section 2's "training vs. search" distinction matters most: block training crawlers, don't block search crawlers;
- You've done the math: defense spend (subscription + conversion lost to false positives + rule-maintenance labor) > scraping losses (bandwidth + server costs) — then spend the money on CDN caching to make scraping cheaper, not on blocking.
Back to the opening line: anti-scraping is cost exchange. If this guide did its job, every dollar you spend from now on buys something you can name — the price difference that makes the scraper "pick another target," not the fantasy of a world without scrapers. Your content deserves protection — but the protection should be the kind you've done the math on.
Comments (0)
Related articles

From 'coffee near me' to live courier tracking: store WGS84, convert for GCJ-02/BD-09 at render, query nearby in two phases (geohash coarse + precise distance), pick a map SDK by compliance first, cache reverse-geocoding by geohash, and treat precise location as sensitive personal data from collection time.

Scan-to-login in six steps, dynamic share codes and channel analytics, one-code-one-use redemption with replay protection, generation options, and WeChat constraints — with a verified runnable Node/Express ticket demo.

Uploaded video is just the start: it needs transcoding, multi-bitrate renditions, HLS packaging and an async queue before smooth playback. This guide gives you the full pipeline diagram, FFmpeg recipes, the HLS sweet spots, a BullMQ state machine, thumbnail/subtitle/moderation branches, and the three cost multipliers to calculate before launch.