Cómo rotar proxies en Python: guía con código

Publicado:

3 min de lectura

Acar Diveroli
Autor: Acar Diveroli
Rotar proxies en Python

Quien lanza muchas peticiones desde Python no llega lejos con una sola dirección. Este artículo muestra cómo ir alternando una lista de proxies dentro del código.

Un proxy oculta tu dirección, pero si envía todas las peticiones seguidas desde la misma IP, salta el límite de peticiones del sitio de destino. Ese es el problema de fondo: no se detecta la dirección, se detecta el patrón. Si no usas un Proxies rotativos sino tu propia lista de direcciones fijas, el cambio lo hace tu código.

Qué es la rotación de IP

Rotar la IP significa cambiar continuamente la dirección de las peticiones salientes: después de cada petición, a intervalos fijos o cuando tú lo decides. En lugar de mandar todo por la misma IP, repartes entre varias.

Con los Proxies residenciales eso ocurre ya en el propio servicio. Quien tiene su lista y no quiere facturar por volumen, construye la rotación por su cuenta: de eso trata este artículo.

Paso 1: requisitos

  • Python 3
  • el entorno de desarrollo que prefieras
  • la biblioteca Requests como cliente HTTP:
bash
pip3 install requests

Paso 2: consigue los proxies

Necesitas una lista de direcciones. En el panel de Proxynet eliges la ubicación acorde al sitio de destino y decides entre Proxies IPv4 e Proxies IPv6.

Paso 3: una petición sin proxy

Como referencia, primero una petición por tu propia conexión:

python
# pip3 install requests
import requests

# send a request to the test endpoint
response = requests.get("https://httpbin.io/ip")

if response.status_code != 200:
    print(f"The request failed with {response.status_code}")
else:
    print(response.text)

La salida muestra tu propia dirección. Apúntala: es la referencia para el paso siguiente.

Paso 4: la misma petición a través de un proxy

Requests recibe los proxies como un diccionario, con una entrada para HTTP y otra para HTTPS:

python
# pip3 install requests
import requests

# specify the proxy server address
proxies = {
    "http": "http://proxy.proxynet.io:60001",
    "https": "http://proxy.proxynet.io:60001",
}

response = requests.get(
    "https://httpbin.io/ip",
    proxies=proxies,
)

if response.status_code != 200:
    print(f"The request failed with {response.status_code}")
else:
    print(response.text)

Si ahora la salida muestra una dirección distinta de la anterior, la petición está saliendo por el proxy.

Paso 5: rotar la lista

Guarda tus proxies, uno por línea, en un archivo como proxies_list.txt:

proxy.proxynet.io:60001
proxy.proxynet.io:60002

Para alternar hay dos caminos.

Por orden

Ir en orden reparte la carga por igual, lo que ayuda con una lista pequeña para que ninguna dirección cargue con todo el trabajo. La pega: la secuencia es regular, y una contraparte atenta detecta justo ahí un patrón.

python
# pip3 install requests
import requests
from itertools import cycle

# read the proxies from the proxy list file
proxies_list = open("proxies_list.txt", "r").read().strip().split("\n")

# create a proxy generator
proxy_pool = cycle(proxies_list)

for _ in range(4):
    proxy = next(proxy_pool)

    proxies = {
        "http": f"http://{proxy}",
        "https": f"http://{proxy}",
    }

    response = requests.get(
        "https://httpbin.io/ip",
        proxies=proxies,
    )

    if response.status_code != 200:
        print(f"The request failed with {response.status_code}")
    else:
        print(response.text)

Al azar

El azar rompe el patrón. A cambio, una dirección puede salir elegida más veces que las demás:

python
# pip3 install requests
import requests
import random

# read the proxies from the proxy list file
proxies_list = open("proxies_list.txt", "r").read().strip().split("\n")

for _ in range(4):
    random_proxy = random.choice(proxies_list)

    proxies = {
        "http": f"http://{random_proxy}",
        "https": f"http://{random_proxy}",
    }

    response = requests.get(
        "https://httpbin.io/ip",
        proxies=proxies,
    )

    if response.status_code != 200:
        print(f"The request failed with {response.status_code}")
    else:
        print(response.text)

No cambies solo la IP

La dirección es un rasgo entre varios. Si el User-Agent es el mismo en todas las peticiones, la combinación delata al bot aunque la IP cambie. Cámbialo también en cada petición —a mano o con una biblioteca como fake-useragent— y deja entre peticiones una pausa breve e irregular.

Conclusión

Python se presta bien al scraping, y la rotación sobre una lista propia se monta con Requests en unas pocas líneas. Si la lista se queda corta o gestionarla se vuelve pesado, un Proxies rotativos hace el mismo trabajo desde el servicio.