A fecha de 7 de octubre de 2026, Shifter cuenta con el mayor pool de IPs estadounidenses activas, más que Oxylabs y Bright Data, a una fracción del coste.Shifter ahora tiene el mayor conjunto de IPs de EE. UU. activas

Ver comparativas

Scraping

Economía de los reintentos: el número de intento en el que reintentar deja de compensar

Cada reintento tiene menos probabilidades de éxito que el anterior. Cómo medir en qué punto reintentar deja de compensar, usando tus propios logs y unas líneas de Python.

Elena Petrova

19 de octubre de 2026 · 8 min de lectura

Todo scraper reintenta las solicitudes fallidas, y la mayoría elige el número de reintentos de la misma manera: tres, porque parece razonable. Pero los reintentos no son gratis. En proxies residenciales facturados por gigabyte, cada reintento vuelve a descargar la página; en cualquier sistema, cuesta tiempo y carga en el objetivo. Y cada reintento suele tener menos probabilidades de éxito que el anterior.

Así que hay un punto en el que otro intento cuesta más de lo que vale. Este estudio muestra cómo encontrarlo a partir de tus propios registros, con un ejemplo práctico y el código para ejecutarlo sobre tus datos.

Por qué los reintentos posteriores tienen menos éxito

Si los fallos fueran pura mala suerte, cada reintento tendría la misma probabilidad de éxito que el primer intento. En la práctica no es así. Una solicitud que falla una vez tiene más probabilidades de estar fallando por una razón persistente: una página que no existe, un bloqueo en esa dirección, un sitio que está caído, un parser que nunca encaja. Los trabajos que llegan al cuarto intento son en su mayoría los casos difíciles.

Eso significa que la tasa de éxito por intento cae, y el coste de cada éxito adicional sube con ella.

Mídelo a partir de tus registros

El único dato que necesitas es, para cada trabajo, el número de intento que tuvo éxito, o una nota de que todos los intentos fallaron. La mayoría de los scrapers ya registran esto. A partir de ahí, la tasa de éxito del intento k es la proporción de trabajos que llegaron al intento k y tuvieron éxito en ese punto.

from collections import Counter


def attempt_success_rates(outcomes, max_attempts):
    """Chance that attempt k succeeds, given the job got that far.

    outcomes: per job, the attempt number that succeeded, or None if every
    attempt failed (with max_attempts tries).
    """
    succeeded_at = Counter(o for o in outcomes if o is not None)
    reached = len(outcomes)
    rates = []
    for k in range(1, max_attempts + 1):
        rates.append(succeeded_at[k] / reached if reached else 0.0)
        reached -= succeeded_at[k]
    return rates


def cost_per_success(rates, cap, attempt_cost):
    """Expected cost of one successful job if we stop after `cap` attempts."""
    p_reach, spent, success = 1.0, 0.0, 0.0
    for rate in rates[:cap]:
        spent += p_reach * attempt_cost
        success += p_reach * rate
        p_reach *= 1 - rate
    return spent / success if success else float("inf")


def best_cap(rates, attempt_cost, value_of_success):
    """The last attempt whose expected value still exceeds its cost."""
    cap = 0
    for k, rate in enumerate(rates, start=1):
        if rate * value_of_success > attempt_cost:
            cap = k
    return cap

Tres funciones:

  • attempt_success_rates convierte tu registro en una tasa de éxito por intento.
  • cost_per_success da el coste medio de un trabajo exitoso si te detienes después de un número dado de intentos.
  • best_cap encuentra el último intento cuyo valor esperado sigue siendo mayor que su coste.

Un ejemplo práctico

Aquí hay un registro ilustrativo de 10.000 trabajos, cada uno con seis intentos permitidos:

from retry_econ import attempt_success_rates, best_cap, cost_per_success

# Illustrative outcomes for 10,000 jobs, each allowed up to six attempts:
# the attempt that succeeded, or None if all six failed.
outcomes = [1] * 8200 + [2] * 900 + [3] * 260 + [4] * 90 + [5] * 40 + [6] * 20 + [None] * 490
rates = attempt_success_rates(outcomes, max_attempts=6)
print("success rate by attempt:", [round(r, 3) for r in rates])

for cap in range(1, 7):
    print(f"cap {cap}: cost per success {cost_per_success(rates, cap, attempt_cost=1.0):.3f}")

print("best cap if a success is worth 5 attempts:", best_cap(rates, attempt_cost=1.0, value_of_success=5.0))
print("best cap if a success is worth 20 attempts:", best_cap(rates, attempt_cost=1.0, value_of_success=20.0))
success rate by attempt: [0.82, 0.5, 0.289, 0.141, 0.073, 0.039]
cap 1: cost per success 1.220
cap 2: cost per success 1.297
cap 3: cost per success 1.357
cap 4: cost per success 1.412
cap 5: cost per success 1.464
cap 6: cost per success 1.514
best cap if a success is worth 5 attempts: 3
best cap if a success is worth 20 attempts: 5

Destacan tres cosas.

La tasa de éxito cae rápido. El primer intento tiene éxito el 82% de las veces. De los trabajos que llegan al segundo intento, la mitad tiene éxito. En el quinto intento, menos de uno de cada diez lo tiene.

Cada éxito adicional cuesta más que el anterior. Dividir el coste de un intento entre su tasa de éxito da el coste de un éxito desde ese intento: alrededor de 1,2 intentos en el primero, 2 en el segundo, 3,5 en el tercero, 7 en el cuarto y más de 25 en el sexto. El coste medio por éxito sube lentamente a medida que permites más intentos, porque cada intento adicional se ejecuta sobre menos trabajos, pero el coste marginal sube de forma pronunciada.

El límite correcto depende de cuánto vale un éxito. Si un registro exitoso vale cinco veces el coste de un intento, detente después de tres. Si vale veinte, como podría ser el caso de una página que necesitas sí o sí, llega hasta cinco. No hay un número único correcto; hay un número correcto para cada valor.

Poner un valor a un éxito

El valor de un éxito es el único dato que tienes que decidir tú. Algunas formas de establecerlo:

  • Registros sustituibles, como una observación de precio entre muchas recogidas a diario, valen poco cada una. Perder una está bien; un límite bajo es lo correcto.
  • Registros necesarios, como una página que completa un conjunto de datos que un cliente está esperando, valen mucho más. Tiene sentido un límite más alto.
  • Costes más allá del ancho de banda también cuentan: el tiempo, la carga en el objetivo y la probabilidad de que insistir en una página que falla provoque un bloqueo para todo lo demás.

En una API de scraping web que solo cobra por las respuestas exitosas, el aspecto económico del reintento recae en el proveedor, pero el tiempo y la carga sobre el objetivo siguen aplicándose. La Web Scraping API de Shifter, por ejemplo, no cobra por las solicitudes fallidas.

Haciendo los reintentos más baratos

El límite es solo la mitad. La otra mitad es hacer que cada reintento tenga más probabilidades de éxito:

  • Espera antes de reintentar, y espera más tiempo cada vez. Muchos fallos son límites de tasa temporales que se resuelven por sí solos.
  • Cambia algo cuando el fallo lo sugiera. Un bloqueo en una dirección puede tener éxito desde otra; un timeout puede necesitar un timeout más largo, no la misma solicitud otra vez.
  • No reintentes lo que no puede tener éxito. Un error 404 o un error de autenticación fallará siempre.

Nuestra guía sobre reintentos y backoff para scrapers web cubre estas técnicas en detalle.

Ejecútalo sobre tus propios datos

  1. Exporta, de una semana de trabajos, el intento que tuvo éxito o un marcador de fallo.
  2. Ejecuta attempt_success_rates con tu máximo actual.
  3. Decide cuánto vale un éxito en intentos.
  4. Establece el límite según lo que devuelva best_cap, por tipo de trabajo si difieren.
  5. Revísalo mensualmente. Las tasas cambian a medida que cambian los sitios y tu configuración.

Preguntas frecuentes

¿Cuántas veces debería reintentar un scraper una solicitud fallida?

Depende de cuán rápido cae tu tasa de éxito por intento y de cuánto vale un registro exitoso. Mide la tasa de éxito de cada intento a partir de tus registros, y luego detente en el último intento cuyo valor esperado siga siendo mayor que su coste. Para muchos trabajos, eso son entre dos y cuatro intentos.

¿Por qué los reintentos tienen menos éxito que los primeros intentos?

Porque los fallos no son aleatorios. Los trabajos que fallan una vez tienen más probabilidades de tener un problema persistente, como una página inexistente o un bloqueo, así que cada intento posterior se extrae de los casos más difíciles.

¿Cuestan dinero los reintentos con proxies residenciales?

Sí. El tráfico de proxies residenciales se factura por volumen, así que cada reintento vuelve a descargar la página. Los intentos fallidos que devuelven páginas de error grandes también cuestan ancho de banda.

¿Debería reintentar los errores 404?

No. Una página que no existe no aparecerá en el siguiente intento. Reintenta solo los fallos que puedan tener éxito más tarde, como los timeouts, los límites de tasa y los errores temporales del servidor.

Conclusión

Reintentar merece la pena hasta que la probabilidad de que el siguiente intento tenga éxito, multiplicada por lo que vale un éxito, cae por debajo del coste de intentarlo. Tus registros ya contienen la tasa de éxito de cada intento; mídela, ponle un valor a un éxito, y establece el límite a partir de los números en lugar de la costumbre.

¿Listo para empezar?

Prueba los proxies residenciales de Shifter, más de 205M IPs, más de 195 países, desde 0,75 $/GB.

Comenzar