Spain Public Procurement Tenders (PLACSP)
Pricing
from $6.00 / 1,000 results
Spain Public Procurement Tenders (PLACSP)
Daily structured export of Spanish government tenders from PLACSP, filtered to your sector by CPV code: buyer, amount, deadline and direct link.
Pricing
from $6.00 / 1,000 results
Rating
0.0
(0)
Developer
Bluewither
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
placsp-licitaciones
Actor de Apify que lee el feed oficial de datos abiertos de la Plataforma de Contratación del Sector Público (PLACSP) y devuelve, por cada licitación: objeto del contrato, importe, organismo, CPV, plazos y enlace.
Pensado como plantilla reutilizable para los siguientes actors del mismo
molde (bundle de portales de empleo, reemplazo del scraper de Instagram, etc.):
la separación feedClient.js (red + paginación) / parser.js (XML → JSON) /
main.js (orquestación + Apify SDK) / monitor/ (vigilancia propia) es el
patrón a copiar.
Estado actual (2026-08-11)
- ✅ Estructura del feed investigada contra datos reales (no documentación de
terceros): capturado y verificado un feed real con Chrome, incluyendo un
ejemplo completo de licitación, una baja (
at:deleted-entry), y las listas oficiales de códigos de estado y de tipo de procedimiento. - ✅ Parser y normalización implementados y probados (
npm test, 5/5 OK) contra una fixture montada con datos reales capturados. - ✅ Actor completo (
src/main.js) probado de punta a punta en local: lee input, calcula "hoy" enEurope/Madridcorrectamente, y maneja errores guardando una señal en el key-value store (ESTADO_MONITOR) para el monitor propio. - ✅ Desplegado y probado con ejecuciones reales en Apify (actor
bluewither/my-actor) — ver "Resultado de las ejecuciones reales" abajo. No hubo ningún bloqueo de IP/WAF: la teoría inicial de riesgo de bloqueo (que aparecía en esta sección antes de hoy) quedó descartada. - ✅ Monitor propio (
monitor/check-run.mjs) y workflow de GitHub Actions listos para desplegar; pendiente de activar con las credenciales reales. - ✅ Ficha de tienda y precio en
STORE_LISTING.md, revisada con datos reales de volumen (no solo estimación).
✅ Resultado de las ejecuciones reales en Apify (2026-08-11)
El actor se desplegó manualmente en Apify (Console Web IDE) y se lanzaron dos runs de prueba contra el feed real de PLACSP, para el día 2026-08-10:
- Feed completo, sin filtro: build correcta (42 s, $0.009) y run correcta (1 min 12 s, $0.019) con 2138 licitaciones extraídas y normalizadas correctamente, recorriendo 5 páginas del feed. Cero errores, cero bloqueos 403/429.
- Filtrado por
cpvPrefijos: ["72"](servicios informáticos), mismo día: run correcta (1 min 8 s, $0.009) con 114 licitaciones — un 5,3% del total nacional, confirmando que el filtro por sector reduce el volumen al orden de magnitud esperado (decenas/bajos cientos, no miles).
Conclusión sobre el riesgo de bloqueo por IP/WAF (la preocupación
original de este documento): la infraestructura de Apify no tiene ningún
problema para leer el feed público de PLACSP. Los 403 Forbidden observados
en sesiones de desarrollo anteriores venían de la lista blanca de salida de
red del entorno de desarrollo en la nube usado para construir este actor
(que solo permite npm/PyPI/GitHub/Anthropic), no de un WAF de PLACSP
bloqueando datacenters en general. No hace falta PlaywrightCrawler ni
proxy de pago: el fetch simple con cabeceras de navegador (src/feedClient.js)
funciona tal cual en producción.
Hallazgo aparte, ya resuelto: el volumen real (2138/día a nivel
nacional) es ~14 veces mayor que la estimación de partida usada para fijar
el precio (~150/día), lo que habría hecho el precio por licitación
inviable para el caso de uso de "toda España cada día". Solución adoptada:
reposicionar el actor en torno al filtrado por CPV/sector (ver
STORE_LISTING.md), donde el volumen real por cliente (114/día para un
sector como TI) sí encaja con el precio propuesto.
Estructura del proyecto
.actor/actor.json Metadatos del actor para Apify.actor/input_schema.json Formulario de input (fecha, filtros, límite páginas)Dockerfile Imagen del actor (apify/actor-node:20)src/config.js Mapeos de códigos oficiales (estado, procedimiento) y cabecerassrc/parser.js XML del feed -> objetos normalizadossrc/feedClient.js Descarga + paginación + filtrado por fechasrc/main.js Orquestación: input -> feed -> dataset + monitormonitor/check-run.mjs Monitor propio (independiente de Apify), para cron externo.github/workflows/monitor.yml Ejemplo de cómo programar el monitor gratis en GitHub Actionstest/parser.test.js Tests con datos reales capturados (npm test)test/sample-feed.atom Fixture: página real de PLACSP + 2 casos sintéticos de bordeSTORE_LISTING.md Propuesta de título, descripción y precio para la tienda
Campos que devuelve cada licitación
expediente, objetoContrato, organismo, jerarquiaOrganismo (cadena de
organismos padre), nifOrganismo, importe (estimado,
totalConImpuestos, totalSinImpuestos, moneda), cpv (array de
códigos), estadoCodigo/estado, procedimientoCodigo/procedimiento,
ubicacion, plazo (fechaLimite, horaLimite), enlace,
perfilContratanteUrl, idExpedienteFeed, uuidTed,
fechaActualizacionFeed, anulada.
Cómo probarlo
npm installnpm test # tests del parser contra datos reales capturadosnode src/main.js # ejecución completa (necesita salida a internet real)
node src/main.js en el entorno de desarrollo en la nube usado para
construir este actor fallará con BloqueoAntiBotError — es la lista blanca
de salida de red de ese entorno, no un bloqueo real de PLACSP (ver
"Resultado de las ejecuciones reales" arriba). Pruébalo desde tu propio
ordenador o, mejor, directamente en Apify, donde funciona sin problema.
Input
Ver .actor/input_schema.json. Por defecto: fecha de hoy (Europe/Madrid),
incluye anuladas, sin filtro de CPV, hasta 200 páginas del feed.
Siguientes pasos (en orden)
- Declarar la actividad a Compliance del banco antes de facturar nada (cuenta de Apify ya creada y actor ya desplegado y probado).
Desplegar este actor y lanzar un run de prueba real✅ hecho (2026-08-11): 2138 licitaciones sin filtro, 114 filtrando por CPV 72, sin bloqueos.Si hace falta, cambiar ano hace falta: elPlaywrightCrawlerfetchsimple funciona en Apify tal cual.- Publicar en la Store con el texto de
STORE_LISTING.md(ya revisado con datos reales de volumen y reposicionado en torno al filtrado por CPV). - Programar el run diario en Apify + el monitor (
monitor/check-run.mjs) en GitHub Actions, con margen antes de la hora estimada del test de Apify. - Con la plantilla ya probada, replicar para el bundle de empleo y, en último lugar, el reemplazo del scraper de Instagram.