← SCRAM AI Lab

Herramientas IA

RPA REPSE/IMSS con Playwright + undetected-chromedriver

Los portales SAT/IMSS detectan headless browsers. Combinación ganadora: undetected-chromedriver para Python + Playwright para flow control. 2captcha y nunca almacenar credenciales del cliente.

May 21, 2026

6 lecturas

El RPA de portales gubernamentales mexicanos no es ingeniería — es contraespionaje

Los portales del SAT, IMSS, REPSE e Infonavit fueron diseñados en 2008 y desde entonces les han pegado parches anti-bot. Detectan Selenium clásico, headless Chrome y user agents genéricos en menos de 3 segundos. Los webdriver.navigator tags están marcados, las fingerprints de canvas se comparan contra blacklists, y el timing de los clicks es analizado. Si vas a hacer RPA serio sobre estos sitios, el stack que aguanta producción en 2026 es undetected-chromedriver (Python) + Playwright para flow control + 2captcha para los retos visuales.

Por qué no Selenium plain ni Playwright headless

  • Selenium clásico: tira en el login del SAT en el 70% de los intentos
  • Playwright headless: tira en captchas reCAPTCHA v3 con score <0.3
  • Chrome real con extensión: funciona pero no escala — necesitas display server

La combinación undetected-chromedriver con Playwright como controlador resuelve: UC parchea las firmas del navegador, Playwright orquesta el flow con su API más robusta que Selenium.

Stack típico

# requirements.txt
playwright==1.49.0
undetected-playwright-patch==1.40.0
2captcha-python==1.5.1
fastapi==0.115.0
rq==2.0.0
redis==5.2.0
from undetected_playwright import stealth_async
from playwright.async_api import async_playwright
from twocaptcha import TwoCaptcha

async def login_sat(rfc: str, password: str, captcha_solver: TwoCaptcha):
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False,  # headed gana
            args=['--disable-blink-features=AutomationControlled'],
        )
        context = await browser.new_context(
            locale='es-MX',
            timezone_id='America/Mexico_City',
            user_agent=REAL_CHROME_UA,
        )
        await stealth_async(context)
        page = await context.new_page()

        await page.goto('https://www.sat.gob.mx/...')
        await page.fill('#rfc', rfc)
        await page.fill('#password', password)

        # captcha image
        captcha_src = await page.locator('img.captcha').get_attribute('src')
        result = captcha_solver.normal(captcha_src)
        await page.fill('#captcha', result['code'])

        await page.click('#submit')
        await page.wait_for_url('**/dashboard', timeout=30000)

Retry con backoff para el SAT a fin de mes

Los portales gubernamentales tiran 503 durante la última semana del mes (declaraciones, reportes IMSS). Tu RPA tiene que respetarlo: si reintentas agresivo, te marcan IP y te bannean por 24h. Patrón: 3 reintentos con backoff exponencial (30s, 90s, 300s) y si tras eso sigue 503, encolar para el siguiente día.

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=30, min=30, max=300),
    retry=retry_if_exception_type((TimeoutError, HTTPError)),
)
async def fetch_repse_status(rfc: str):
    return await rpa_session.fetch(rfc)

Arquitectura en producción

Un worker FastAPI recibe la solicitud (autenticada por JWT del CRM), encola un job en Redis Queue, un pool de 4 workers Python con undetected-chromedriver corre los flows en contenedores Docker. Cada worker tiene su propio display virtual (Xvfb) porque headed > headless. Pool size limitado por costo de 2captcha (~$0.003 USD por captcha resuelto).

Compliance no negociable

Nunca almacenar credenciales del cliente. Cada sesión de RPA pide login interactivo desde la UI del cliente, las credenciales viven en memoria del worker durante la sesión y se purgan al terminar. Si el cliente quiere "recordame", esa decisión la toma el CFO/CISO del cliente firmando algo, no tu equipo de devs. Hemos visto demandas civiles por esto.

  • No localStorage, no Redis, no Postgres con credenciales
  • Logs estructurados con RFC hasheado, nunca el password
  • Auditoría: cada RPA run logueado con timestamp, RFC hash, acción, resultado
  • Time-box: sesiones expiran en 15 min de inactividad

El gato y el ratón continúa

El SAT actualizó sus detecciones en marzo 2025; UC tardó 3 semanas en parchear. Si tu negocio depende de RPA sobre portales gubernamentales, tu plan B siempre debe ser "operador humano con script semi-asistido". Automatizamos lo que no es crítico, dejamos al humano lo que cuesta una multa.

La pregunta del decenio: ¿cuánto falta para que el SAT exponga una API oficial decente y este artículo sea histórico? Spoiler: no en este sexenio.

rpa
sat
imss
playwright
← Volver a SCRAM AI Lab