Una tabla HTML vacía no siempre significa que la respuesta no contenga registros de proxy. Algunas listas colocan objetos JSON dentro de llamadas JavaScript y rellenan las filas más tarde.

Para una fuente ya obtenida que utilice el contenedor específico gp.insertPrx seguido de un objeto JSON:

import ipaddress
import json
import re

decoder = json.JSONDecoder()
endpoints = set()
for marker in re.finditer(r"gp[.]insertPrx\(\s*", html):
    try:
        row, end = decoder.raw_decode(html, marker.end())
        if not isinstance(row, dict):
            continue
        address = ipaddress.ip_address(row["PROXY_IP"])
        port = int(row["PROXY_PORT"], 16)
    except (ValueError, KeyError, TypeError):
        continue
    if 1 <= port <= 65535 and html[end:].lstrip().startswith(");"):
        endpoints.add((str(address), port))

html es el texto de la fuente, no un objeto del navegador. La expresión regular encuentra un contenedor conocido; JSONDecoder determina dónde termina su valor JSON. Así se evita intentar analizar JSON anidado solo con una expresión regular.

El campo de puerto del ejemplo es explícitamente hexadecimal: C38 significa 3128 decimal. No aplique la base 16 al campo decimal de otro proveedor solo porque ambos se llamen puerto.

Esto es un analizador para el formato indicado, no un intérprete de JavaScript. Los literales de objeto con comillas simples, los valores calculados y otras expresiones de JavaScript necesitan otra interfaz de datos documentada. No ejecute código arbitrario de la página para obtener una lista de puntos finales.

Valide el contrato de la fuente y conserve los campos de protocolo por separado. Si la fuente tiene filas HTML rellenadas, use extracción de puntos finales por fila en lugar de este analizador de contenedores JavaScript. Extraer una dirección y un puerto no demuestra que el punto final ofrezca actualmente un servicio de proxy utilizable.

Artículos relacionados