Ir al contenido
GProxy
Registro
Гайды 6 min de lectura 33 vistas

Raspado web con proxy usando Beautiful Soup y requests

Esta guía detalla cómo integrar proxies con Beautiful Soup y requests para un raspado web robusto. Evita los bloqueos

Python Парсинг
Raspado web con proxy usando Beautiful Soup y requests

Scraping con Beautiful Soup y requests usando un proxy implica configurar la librería requests para enrutar el tráfico web a través de un servidor proxy especificado antes de analizar el contenido HTML con Beautiful Soup, lo que permite la rotación de IP, eludir las restricciones geográficas y mitigar los bloqueos de IP.

Al realizar web scraping, las solicitudes directas desde una única dirección IP pueden provocar limitaciones de velocidad (rate limiting), prohibiciones de IP temporales o permanentes, o contenido geo-restringido. Los servicios de proxy abordan estos desafíos enrutando las solicitudes a través de diferentes direcciones IP, haciendo que el scraping sea más robusto y escalable.

Las librerías principales para esta tarea son:
* requests: Una librería HTTP para Python, que simplifica el envío de solicitudes HTTP.
* Beautiful Soup: Una librería de Python para analizar documentos HTML y XML.

Configuración de Proxies con requests

La librería requests soporta la configuración de proxies a través del parámetro proxies en sus métodos de solicitud.

Configuración de un único Proxy

Para usar un único proxy, proporciona un diccionario que mapee los protocolos (HTTP, HTTPS) a la URL del proxy.

import requests

proxy_http = "http://your_proxy_ip:port"
proxy_https = "https://your_proxy_ip:port" # A menudo idéntico a HTTP

proxies = {
    "http": proxy_http,
    "https": proxy_https,
}

try:
    response = requests.get("http://httpbin.org/ip", proxies=proxies, timeout=10)
    response.raise_for_status()
    print("External IP:", response.json().get('origin'))
except requests.exceptions.RequestException as e:
    print(f"Request failed: {e}")

Autenticación de Proxy

Para proxies que requieren autenticación, incrusta las credenciales directamente en la URL del proxy.

import requests

proxy_user = "your_username"
proxy_pass = "your_password"
proxy_host = "your_proxy_ip"
proxy_port = "port"

authenticated_proxy = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"

proxies = {
    "http": authenticated_proxy,
    "https": authenticated_proxy,
}

try:
    response = requests.get("http://httpbin.org/ip", proxies=proxies, timeout=10)
    response.raise_for_status()
    print("External IP (authenticated):", response.json().get('origin'))
except requests.exceptions.RequestException as e:
    print(f"Authenticated request failed: {e}")

Rotación de Proxies

Para el scraping a gran escala, rotar a través de una lista de proxies es esencial para distribuir las solicitudes y minimizar el riesgo de ser bloqueado.

import requests
import random
import time

proxy_list = [
    "http://user1:pass1@proxy1.example.com:8000",
    "http://user2:pass2@proxy2.example.com:8000",
    "http://user3:pass3@proxy3.example.com:8000",
]

def get_random_proxy():
    return random.choice(proxy_list)

def make_proxied_request(url, headers=None, attempt_limit=3):
    for attempt in range(attempt_limit):
        proxy_url = get_random_proxy()
        proxies = {"http": proxy_url, "https": proxy_url}
        try:
            print(f"Attempt {attempt + 1}: Using proxy {proxy_url.split('@')[-1]} for {url}")
            response = requests.get(url, proxies=proxies, headers=headers, timeout=15)
            response.raise_for_status()
            return response
        except requests.exceptions.RequestException as e:
            print(f"Proxy request failed (attempt {attempt + 1}): {e}")
            time.sleep(random.uniform(2, 5)) # Delay before retrying with a new proxy
    return None

# Example usage with a dummy URL
try:
    target_url = "http://quotes.toscrape.com/"
    response = make_proxied_request(target_url)
    if response:
        print(f"Successfully fetched {target_url} with status code {response.status_code}")
except Exception as e:
    print(f"Failed to fetch {target_url} after multiple retries: {e}")

Análisis de HTML con Beautiful Soup

Beautiful Soup transforma el contenido HTML de una respuesta de requests en un objeto Python navegable.

from bs4 import BeautifulSoup

html_doc = """
<html>
<head><title>Example Page</title></head>
<body>
<p class="intro"><b>Welcome!</b></p>
<div id="content">
    <a href="/item1" class="product-link">Product A</a>
    <a href="/item2" class="product-link">Product B</a>
</div>
</body>
</html>
"""

soup = BeautifulSoup(html_doc, 'html.parser')

# Accessing elements
print("Page Title:", soup.title.string)

# Finding specific elements
intro_paragraph = soup.find('p', class_='intro')
print("Intro text:", intro_paragraph.get_text(strip=True))

# Finding all elements by class
product_links = soup.find_all('a', class_='product-link')
for link in product_links:
    print(f"Product: {link.get_text()}, URL: {link['href']}")

Integración de Proxies con Beautiful Soup Scraping

La combinación de la configuración de proxy con el análisis de Beautiful Soup permite un flujo de trabajo de scraping completo.

import requests
from bs4 import BeautifulSoup
import random
import time

# --- Proxy Configuration (as defined previously) ---
proxy_list = [
    "http://user1:pass1@proxy1.example.com:8000",
    "http://user2:pass2@proxy2.example.com:8000",
    # Add more proxies from your service
]

def get_random_proxy():
    return random.choice(proxy_list)

def make_proxied_request(url, headers=None, attempt_limit=3):
    for attempt in range(attempt_limit):
        proxy_url = get_random_proxy()
        proxies = {"http": proxy_url, "https": proxy_url}
        try:
            print(f"Attempt {attempt + 1} for {url}: Using proxy {proxy_url.split('@')[-1]}")
            response = requests.get(url, proxies=proxies, headers=headers, timeout=15)
            response.raise_for_status()
            return response
        except requests.exceptions.RequestException as e:
            print(f"Request failed (attempt {attempt + 1}): {e}")
            time.sleep(random.uniform(2, 5))
    return None

# --- Scraping Logic ---
def scrape_quotes(url):
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    }

    response = make_proxied_request(url, headers=headers)

    if response:
        soup = BeautifulSoup(response.text, 'html.parser')
        quotes = soup.find_all('div', class_='quote')

        data = []
        for quote in quotes:
            text = quote.find('span', class_='text').get_text(strip=True)
            author = quote.find('small', class_='author').get_text(strip=True)
            tags = [tag.get_text(strip=True) for tag in quote.find_all('a', class_='tag')]
            data.append({"text": text, "author": author, "tags": tags})
        return data
    return []

# --- Execution ---
if __name__ == "__main__":
    target_url = "http://quotes.toscrape.com/"
    print(f"Starting scrape of {target_url}")
    scraped_data = scrape_quotes(target_url)

    if scraped_data:
        print(f"Scraped {len(scraped_data)} quotes:")
        for i, quote in enumerate(scraped_data[:3]): # Print first 3 for brevity
            print(f"  {i+1}. Author: {quote['author']}, Quote: {quote['text'][:50]}...")
    else:
        print("No data scraped.")

Mejores Prácticas y Consideraciones

Encabezados User-Agent

Los servidores web a menudo inspeccionan el encabezado User-Agent para identificar al cliente. Un User-Agent predeterminado de requests puede indicar un bot. Imitar un User-Agent de navegador común reduce la detección.

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Connection": "keep-alive",
}
response = requests.get(url, proxies=proxies, headers=headers)

Retrasos en las Solicitudes y Limitación de Velocidad

Las solicitudes rápidas pueden activar límites de velocidad o prohibiciones de IP. Implementa retrasos entre solicitudes, especialmente al rotar proxies. time.sleep() con un rango de retraso aleatorio es efectivo.

import time
import random
# ... inside a loop processing multiple URLs ...
time.sleep(random.uniform(2, 7)) # Wait between 2 and 7 seconds
response = make_proxied_request(next_url, headers=headers)

Manejo de Errores

El scraping robusto requiere un manejo integral de errores para problemas de red, fallos de proxy y respuestas del servidor.
* requests.exceptions.RequestException: Captura todos los errores relacionados con requests (conexión, tiempo de espera, errores HTTP).
* Códigos de Estado HTTP: Verifica response.status_code. Códigos como 403 (Prohibido), 404 (No encontrado), 429 (Demasiadas solicitudes) o 5xx (Error del servidor) indican problemas.
* Tiempos de Espera (Timeouts): Configura un parámetro timeout en requests.get() para evitar esperas indefinidas.

CAPTCHAs y Medidas Anti-Scraping Avanzadas

Algunos sitios web emplean mecanismos de detección avanzados como CAPTCHAs o desafíos de JavaScript. Los proxies ayudan con la rotación de IP, pero no resuelven estos problemas directamente. Para tales casos, considera navegadores sin interfaz gráfica (headless browsers) (ej., Selenium, Playwright) o servicios especializados de resolución de CAPTCHAs.

Comparación de Tipos de Proxy

Característica Proxies de Centros de Datos Proxies Residenciales
Fuente de IP Servidores comerciales, proveedores de la nube Dispositivos de usuarios reales (escritorios, móviles) con IPs de ISP
Anonimato Alto, pero las IPs suelen ser reconocidas como de centro de datos Muy alto, las IPs aparecen como usuarios legítimos
Costo Generalmente más bajo Significativamente más alto
Velocidad Típicamente más rápido, menor latencia Puede ser más lento, mayor latencia
Riesgo de Detección Mayor riesgo de ser detectado/bloqueado Menor riesgo, ideal para eludir medidas anti-bot estrictas
Casos de Uso Scraping general, datos públicos, sitios menos protegidos Objetivos de alto valor, e-commerce, redes sociales, geolocalización

Consideraciones Legales y Éticas

  • robots.txt: Respeta el archivo robots.txt de un sitio web, que especifica las reglas para los rastreadores web. Accede a él en http://example.com/robots.txt.
  • Términos de Servicio: Revisa los términos de servicio de un sitio web. El scraping puede estar prohibido.
  • Uso de Datos: Asegura el cumplimiento de las regulaciones de protección de datos (ej., GDPR, CCPA).
  • Impacto en el Servidor: Evita sobrecargar el servidor objetivo con solicitudes. Implementa retrasos apropiados.
Actualizado: 04.03.2026
Volver a la categoría

Pruebe nuestros proxies

20,000+ proxies en 100+ países del mundo

support_agent
GProxy Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.