El web scraping de portales gubernamentales en México presenta desafíos únicos: captchas propietarios, sesiones frágiles, y interfaces que cambian sin previo aviso. Esta guía cubre los patrones más comunes para automatizar el SAT, IMSS, y otros portales de gobierno usando Python.
Los desafíos del scraping gubernamental en México
- Captchas propietarios — El SAT e IMSS usan captchas de imagen propios, no reCAPTCHA
- Sesiones con tiempo de vida corto — Las sesiones expiran en 5-15 minutos
- Navegación con ViewState — Muchos portales usan ASP.NET con ViewState
- Rate limiting agresivo — Demasiadas peticiones = bloqueo temporal
- Sin APIs públicas — Todo debe hacerse via scraping web
Patrón base: Sesión con captcha
El patrón más común en portales del SAT:
import requests
import base64
from ocilar import OcilarClient
ocilar = OcilarClient(api_key="sk-...")
session = requests.Session()
# 1. Cargar la página principal (obtener cookies)
session.get("https://portalcfdi.facturaelectronica.sat.gob.mx/")
# 2. Descargar imagen del captcha
captcha_resp = session.get(
"https://portalcfdi.facturaelectronica.sat.gob.mx/datosFactura/CaptchaImage"
)
image_b64 = base64.b64encode(captcha_resp.content).decode()
# 3. Resolver con Ocilar (menos de 70ms)
result = ocilar.solve_sat(image_base64=image_b64)
# 4. Enviar login con el captcha resuelto
login_data = {
"rfc": "JUAJ850101XXX",
"password": "tu_ciec",
"captcha": result.text,
}
session.post("https://portalcfdi.facturaelectronica.sat.gob.mx/login", data=login_data) Scraping del SAT: Descarga de CFDIs
Una vez autenticado, puedes consultar y descargar CFDIs por rango de fechas:
# Consultar CFDIs emitidos
params = {
"fecha_inicio": "2026-01-01",
"fecha_fin": "2026-03-22",
"tipo": "emitidos",
}
cfdi_list = session.post(
"https://portalcfdi.facturaelectronica.sat.gob.mx/consulta",
data=params
)
# Descargar cada CFDI en XML
for cfdi in parse_results(cfdi_list.text):
xml = session.get(cfdi["download_url"])
with open(f"cfdis/{cfdi['uuid']}.xml", "wb") as f:
f.write(xml.content) Scraping del IMSS
El IMSS tiene su propio captcha y flujo de autenticación:
# IMSS tiene un captcha diferente al SAT
captcha_resp = session.get("https://serviciosdigitales.imss.gob.mx/captcha")
image_b64 = base64.b64encode(captcha_resp.content).decode()
# Ocilar tiene un modelo específico para IMSS
result = ocilar.solve_imss(image_base64=image_b64)
# Continuar con el login del IMSS
session.post("https://serviciosdigitales.imss.gob.mx/login", data={
"nss": "12345678901",
"curp": "JUAJ850101HDFRZL09",
"captcha": result.text,
}) Extracción de datos de documentos
Además de resolver captchas, Ocilar puede extraer datos estructurados de documentos mexicanos:
Constancia de Situación Fiscal (CSF)
# Extraer datos de una CSF en PDF
with open("constancia_sf.pdf", "rb") as f:
file_b64 = base64.b64encode(f.read()).decode()
csf = ocilar.extract_csf(file_base64=file_b64)
print(csf.data["rfc"]) # "JUAJ850101XXX"
print(csf.data["nombre"]) # "JULIO ALBERTO JUAREZ"
print(csf.data["regimen_fiscal"]) # "612 - Personas Físicas con Actividades Empresariales" INE (Credencial para Votar)
with open("ine_front.jpg", "rb") as f:
front_b64 = base64.b64encode(f.read()).decode()
with open("ine_back.jpg", "rb") as f:
back_b64 = base64.b64encode(f.read()).decode()
ine = ocilar.extract_ine(front_base64=front_b64, back_base64=back_b64)
print(ine.data["nombre"]) # "JULIO ALBERTO"
print(ine.data["curp"]) # "JUAJ850101HDFRZL09"
print(ine.data["clave"]) # "091234567890" Mejores prácticas
- Respeta los rate limits — Usa delays de 1-3 segundos entre peticiones
- Maneja sesiones correctamente — Renueva antes de que expiren
- Implementa reintentos — Los portales del gobierno fallan frecuentemente
- Guarda las cookies — Reutiliza sesiones cuando sea posible
- Registra todo — Los portales cambian sin aviso, necesitarás logs para debuggear
Costos
Con Ocilar, el costo por resolver captchas del SAT o IMSS es de $0.10 USD por cada 1,000. Si tu proceso descarga 10,000 CFDIs al mes y cada uno requiere un captcha, el costo total es $1.00 USD al mes.