Un bloqueo de Cloudflare puede detener un proyecto de scraping durante semanas si adivinas la causa. Este manual de 3 días aísla sistemáticamente la capa (TLS, encabezados, IP, desafío JS) que está desencadenando el bloqueo y lo soluciona, utilizando Scavio como comparación de verdad sobre el terreno.
Requisitos previos
- Python 3.10+
- Una clave API de Scavio
- Una URL bloqueada
- tls-client o curl_cffi
Guia paso a paso
Paso 1: Día 1 por la mañana: confirme el éxito de Scavio
Establecer que el objetivo es técnicamente descartable.
import requests, os
API_KEY = os.environ['SCAVIO_API_KEY']
def scavio_ground_truth(url):
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'query': url, 'platform': 'extract', 'render_js': True})
html = r.json().get('html', '')
return len(html) > 1000 and 'challenge' not in htmlPaso 2: Día 1 por la tarde: prueba de huellas dactilares TLS
Cambie a tls_client con un navegador JA3 real.
from tls_client import Session
s = Session(client_identifier='chrome_120')
print(s.get('https://target.com').status_code)Paso 3: Día 2: verificación de paridad de encabezados
Haga coincidir el orden completo del encabezado de Chrome a través de curl_cffi.
from curl_cffi import requests as cf
print(cf.get('https://target.com', impersonate='chrome120').status_code)Paso 4: Día 2 por la tarde: rotación de IP
Proxy residencial o ISP si la IP del centro de datos está marcada.
# Use your proxy provider
PROXY = {'http': 'http://user:[email protected]:port'}
cf.get('https://target.com', impersonate='chrome120', proxies=PROXY)Paso 5: Día 3: recurra a Scavio si falla la autoreparación
Si las 3 capas aún están bloqueadas, dirígete a través de Scavio mientras dure.
def safe_fetch(url):
try:
r = cf.get(url, impersonate='chrome120', proxies=PROXY)
if r.status_code == 200 and 'challenge' not in r.text: return r.text
except: pass
# fallback
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY}, json={'query': url, 'platform': 'extract'})
return r.json().get('html', '')Ejemplo en Python
import os, requests
API_KEY = os.environ['SCAVIO_API_KEY']
def safe_fetch(url):
try:
html = requests.get(url, timeout=10).text
if 'challenge' not in html: return html
except: pass
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'query': url, 'platform': 'extract', 'render_js': True})
return r.json().get('html', '')
print(len(safe_fetch('https://cloudflare-blocked.com')))Ejemplo en JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
export async function safeFetch(url) {
try {
const r = await fetch(url);
const html = await r.text();
if (!html.includes('challenge')) return html;
} catch {}
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: url, platform: 'extract', render_js: true })
});
return (await r.json()).html;
}Salida esperada
3 days: diagnosis + fix or stable fallback. Typical outcome: 60% of teams fix the block with tls_client + residential IP, 40% stay on Scavio long-term.