Entrega automática tras confirmar el pago · IP dedicado · Soporte por ticket en el panel Pago local según tu país · Precios en dólares (USD)
ProxyBox
Datos

Web scraping con Python en la práctica: del primer script al recolector que aguanta

Cómo montar un recolector en Python con requests y BeautifulSoup, cuándo cambiarlo por una API, cómo respetar los límites y dónde entra de verdad el proxy.

Por Redacción ProxyBox · Editor técnico 7 min de lectura Python · web scraping · requests
Guía completa de Datos

Este artículo profundiza en un punto del tema. Para la visión completa, lee Qué es el web scraping: cómo funciona, cuándo es legítimo y dónde entra el proxy.

Un recolector en Python empieza con cinco líneas que funcionan a la primera. El problema llega después: en la tercera semana, cuando el sitio cambia un div; en el segundo mes, cuando empiezan a llegar respuestas de error; en el sexto, cuando alguien pregunta de dónde salió ese dato.

Este artículo trata de esa segunda parte. Si todavía estás decidiendo si necesitas recolectar, empieza por qué es el web scraping, que trata la base legal y los casos en los que la fuente oficial lo resuelve sin raspar nada.

Antes de la primera línea: ¿hay una API?

Sigue siendo la pregunta que más trabajo ahorra. Un endpoint oficial devuelve datos estructurados, no se rompe cuando el sitio cambia de diseño, consume una fracción del tráfico y no abre ninguna discusión sobre términos de uso.

En muchos países, buena parte de lo que la gente intenta raspar ya está publicado como dato abierto: contratación pública, registros de empresas, estadísticas oficiales. Conviene revisar la fuente antes de escribir el recolector.

La pareja que resuelve la mayoría de los casos

Para una página que ya llega completa en el HTML, requests descarga y BeautifulSoup extrae:

import requests
from bs4 import BeautifulSoup

sessao = requests.Session()
sessao.headers.update({
    "User-Agent": "MeuColetor/1.0 ([email protected])",
    "Accept-Language": "pt-BR,pt;q=0.9",
})

resposta = sessao.get("https://exemplo.com.br/produtos", timeout=20)
resposta.raise_for_status()

pagina = BeautifulSoup(resposta.text, "html.parser")
for item in pagina.select(".produto"):
    nome = item.select_one(".nome")
    preco = item.select_one(".preco")
    print(nome.get_text(strip=True), preco.get_text(strip=True))

En tu caso, cambia el User-Agent por el nombre de tu recolector y un contacto tuyo, Accept-Language por el idioma del sitio (por ejemplo, es-ES,es;q=0.9), la URL por la de tu destino y los selectores .produto, .nome y .preco (producto, nombre y precio) por los de la página.

Tres detalles de este fragmento son los que separan un script de un recolector:

Session() en lugar de requests.get suelto. Reutiliza la conexión, lo que reduce el tiempo y el consumo. En una recolección grande, la diferencia es grande.

Un User-Agent que dice quién eres. Un agente honesto, con una forma de contacto, es lo que permite al administrador del sitio hablar contigo en lugar de bloquearte sin más. Es la diferencia entre ser un socio pesado y un problema anónimo.

timeout siempre. Sin él, una petición colgada bloquea el recolector por tiempo indefinido.

Selecciona por lo que es estable

Un motivo muy común de un recolector roto es un selector frágil. Las clases generadas automáticamente cambian con cada publicación del sitio.

Prioriza, en este orden: atributos de datos (data-produto-id), identificadores semánticos, estructura de tabla y, solo al final, clases de estilo. Y mucho antes de eso, busca un bloque <script type="application/ld+json"> en la página: muchos sitios de comercio publican ahí el precio y el nombre del producto en JSON limpio, listos para leer sin ningún selector.

Despacio es más rápido

La tentación es ejecutarlo todo en paralelo. El resultado suele ser un bloqueo el primer día.

import time, random

for url in urls:
    resposta = sessao.get(url, timeout=20)
    if resposta.status_code == 429:
        espera = int(resposta.headers.get("Retry-After", 60))
        time.sleep(espera)
        continue
    processa(resposta)
    time.sleep(random.uniform(1.5, 4.0))

Este código hace dos cosas que casi ningún recolector aficionado hace: lee Retry-After en lugar de reintentar al instante, y varía el intervalo en lugar de ir al compás del reloj. El significado exacto del 429 y la estrategia de espera creciente están en error 429 Too Many Requests.

Antes que nada, lee el robots.txt del sitio y sus términos de uso. No es una formalidad: es lo que define si tu recolección es aceptable.

Cuándo hace falta el navegador (y por qué evitarlo)

Si el contenido solo aparece después de ejecutarse el JavaScript, requests no sirve y entra un navegador automatizado. Antes de aceptar ese coste, abre las herramientas de desarrollo en la pestaña de red y busca la llamada que hace la propia página: en muchos casos hay un endpoint JSON detrás, que devuelve el mismo dato sin renderizar nada.

Cuando el navegador es inevitable, el coste cambia de escala: cada página carga imágenes, fuentes y scripts, y el consumo de tráfico se dispara. Las cuentas están en consumo de GB en scraping, y conviene bloquear imágenes y fuentes en la carga. Qué herramienta elegir está en Selenium, Puppeteer o Playwright.

Dónde entra de verdad el proxy

Al principio, no entra. Una recolección pequeña de páginas públicas sale por tu propia conexión sin ningún problema.

Empieza a tener sentido en tres situaciones:

  • El servidor cuenta por dirección. El volumen ha crecido y empiezas a tocar el límite. La salida es repartir, siempre junto con la reducción de la frecuencia, nunca en su lugar.
  • El contenido cambia según el origen. El precio, el catálogo y los resultados de búsqueda varían según el país o la ciudad de quien pide. Ahí una dirección del país correcto no es una optimización: es un requisito para que el dato sea correcto.
  • La recolección tiene que mantener la sesión iniciada. En ese caso, cambiar de dirección en mitad de la sesión es justo lo que dispara la alerta, y lo correcto es una dirección fija.

La configuración en requests, httpx y aiohttp, con usuario y contraseña y el tratamiento de contraseñas con caracteres especiales, está en la guía de proxy en Python. La elección entre dirección fija, por sesión o por petición está en proxy rotativo: fija, por sesión o por petición.

Conviene medir antes de contratar: ejecuta cien elementos, mide el tráfico consumido y proyecta. La página de proxy para web scraping muestra los productos por escenario: nuestro residencial rotativo por GB sale con IP de Brasil, y para otros países vendemos IP fija por país (IPv4, ISP e IPv6), que eliges en el checkout.

La lista del recolector que dura

  1. Comprobaste si hay API o dato abierto en la fuente.
  2. Leíste el robots.txt y los términos de uso.
  3. Definiste la base legal si hay datos personales (RGPD en la UE y las leyes locales de protección de datos).
  4. Usas Session, timeout y un User-Agent identificable.
  5. Seleccionas por atributos estables, no por clases de estilo.
  6. Respetas Retry-After y varías el intervalo.
  7. Registras la tasa de errores y avisas cuando sube.
  8. Solo entonces valoras el proxy, según el tipo de límite que apareció.

Un recolector montado en este orden cuesta menos en tráfico, se rompe menos cuando el sitio cambia y no pone a nadie en una situación difícil.

Preguntas frecuentes

¿Qué biblioteca uso para hacer web scraping en Python?
En la mayoría de los casos, requests para descargar y BeautifulSoup para extraer. Scrapy compensa cuando hay muchas páginas y reglas de cola. Un navegador automatizado solo cuando el contenido depende de JavaScript, porque cuesta mucho más en tiempo y en tráfico.
¿Necesito un proxy para hacer scraping con Python?
Al principio, casi nunca. El proxy entra cuando el volumen crece y el servidor empieza a contar peticiones por dirección, o cuando el contenido cambia según el país de origen.
¿Cómo evito el error 429 en Python?
Reduce la frecuencia, respeta la cabecera Retry-After cuando llegue y haz que la espera crezca con cada nuevo fallo. Solo después piensa en repartir las peticiones entre direcciones.
¿Es legal hacer web scraping con Python?
El lenguaje no cambia la respuesta. Lo que la define es la fuente, los términos de uso del sitio, el tipo de dato recogido y la base legal cuando hay datos personales. Recoger páginas públicas con moderación no es lo mismo que copiar una base de datos protegida.

¿Quieres aplicarlo en tu operación?

Precio público en dólares, pago local según tu país y entrega automática en el panel tras confirmar el pago. Si no sabes qué tipo elegir, cuéntanos tu operación por WhatsApp: te indicamos el más barato que lo resuelve.

Este contenido es informativo. Un proxy es infraestructura de red: controlamos el origen, la exclusividad y la geolocalización del IP. La aprobación o restricción de cuentas depende también del comportamiento de uso, la huella digital del navegador y las políticas internas de cada plataforma. Consulta la política de uso aceptable.

¿Tienes dudas? Escríbenos por WhatsApp