Manual de CrawlForge (CLI)
Versión en inglés: read the manual in English — la inglesa es la que manda. Esta traducción puede ir por detrás; si las dos discrepan, la buena es la otra.
La herramienta es hoy línea de comandos. Una interfaz gráfica está prevista y no existe todavía.
Esto no repite el
--help, que ya está completo y en inglés. Esto es qué comando usar en cada situación real, con los sitios de verdad.
0. Antes de empezar
El binario ya está instalado y en el PATH:
crawlforge --version
Si no responde, se reinstala desde el repositorio:
cd ~/Desarrollos/proyectos/proyectos-mini/crawlforge
cargo build --release -p crawlforge && cp target/release/crawlforge ~/.cargo/bin/
La salida de la herramienta está en inglés. Es el idioma de origen; los demás son
traducciones, y se piden con --lang en los comandos que leen un rastreo (report, inspect,
diff, portfolio, rules):
crawlforge rules --lang es
crawlforge report crawl.sqlite --lang es
--lang |
Idioma |
|---|---|
en |
Inglés — el de por defecto y el de origen |
es |
Español |
de |
Alemán |
fr |
Francés |
it |
Italiano |
nl |
Neerlandés |
tr |
Turco |
pt |
Portugués |
ja |
Japonés |
pl |
Polaco |
Se acepta una región o una codificación y se ignora (pt-BR, es_ES.UTF-8): hay un solo
portugués, un solo español. Un idioma cuya traducción aún no está escrita se acepta y sale en
inglés —números incluidos— hasta que lo esté; un valor desconocido es un error que lista estos
códigos. La ayuda (--help) y los errores de argumentos van siempre en inglés.
Para no repetirlo en cada comando, en tu ~/.zshrc. La variable fija también el idioma de
crawl, audit y list, que no tienen --lang; ahí un valor desconocido se ignora y la salida
sigue en inglés:
export CRAWLFORGE_LANG=es
1. El flujo de un día normal
Cuatro comandos. Si solo lees una sección del manual, que sea esta.
# 1. Rastrear
crawlforge crawl https://tusitio.com/
# 2. Ver qué ha salido, aquí mismo
crawlforge report crawl-tusitio-com.sqlite --lang es
# 3. Llevárselo a alguien que no usa terminal
crawlforge export crawl-tusitio-com.sqlite --format xlsx --out auditoria.xlsx
# 4. Un informe para pegar en un ticket o mandar por correo
crawlforge report crawl-tusitio-com.sqlite --format html --out informe.html --lang es
Cada comando termina diciéndote cuál es el siguiente, con la orden lista para copiar. No hace falta memorizar nada.
Los ficheros que aparecen
| Fichero | Qué es |
|---|---|
crawl-<sitio>.sqlite |
El rastreo. Todo está aquí: URLs, enlaces, imágenes, hallazgos, cabeceras. Es un SQLite normal; se puede abrir con cualquier visor. |
crawl-<sitio>.prev.sqlite |
El rastreo anterior, apartado automáticamente al repetir. Es lo que diff necesita. No lo borres. |
Un rastreo se puede volver a mirar meses después sin volver a rastrear: report, export y
diff trabajan sobre el fichero, no sobre la red.
2. Recetas
Rastrear un sitio entero
crawlforge crawl https://cliente.com/
Descubre los sitemaps, respeta robots.txt y para cuando agota el sitio. Va con 5 peticiones
simultáneas, que es prudente para un WordPress. En un sitio propio y bien dimensionado:
crawlforge crawl https://tusitio.com/ --concurrency 10
No subas la concurrencia en sitios de terceros ni en hosting compartido. Un servidor con limitación por IP empieza a devolver 503 tras varios rastreos seguidos, y a partir de ahí las mediciones no valen nada: lo que estás midiendo es su defensa, no tu sitio.
Solo una parte del sitio
# Solo el blog
crawlforge crawl https://cliente.com/ --include "/blog/"
# Todo menos el área de administración y las URLs de respuesta a comentarios
crawlforge crawl https://cliente.com/ --exclude "/wp-admin/" --exclude "\?replytocom="
Son expresiones regulares sin anclar: una cadena normal funciona como «contiene». --exclude
gana sobre --include, y lo excluido queda registrado como excluido en el informe: no
desaparece sin dejar rastro.
Una prueba rápida, sin rastrear las 176.000 URLs
crawlforge crawl https://tumedio.com/ --max-urls 500
Ojo con esto: un rastreo truncado no puede juzgar el grafo de enlaces. La herramienta lo sabe y silencia las reglas que dependen de tenerlo completo —páginas huérfanas, profundidad excesiva— en lugar de inventarse el veredicto. Si el informe no las menciona, no es que estén bien; es que no se han podido evaluar.
Auditar antes de desplegar
Sobre la carpeta compilada, sin subir nada a ningún sitio:
crawlforge audit ./dist --base https://tusitio.com/
--base es obligatorio y por un motivo: los canonical absolutos del sitio se comparan contra
esa URL. Con una falsa, la auditoría de indexabilidad no significa nada, y la herramienta avisa
si el 80% de los canonicals contradicen lo que le has dicho.
Es el modo más rápido de todos —no hay red— y es el que se usa en CI.
Comparar dos rastreos: ¿el despliegue ha empeorado algo?
crawlforge diff crawl-sitio.prev.sqlite crawl-sitio.sqlite --lang es
Esto es lo que Screaming Frog no te da. Un rastreo es una foto; el diff te dice si lo de ayer sigue igual. Como puerta de CI, que falle si aparece algo grave:
crawlforge diff antes.sqlite despues.sqlite --fail-on high
Sale con código distinto de cero si aparece un hallazgo nuevo de severidad high o peor. Un
--fail-on INDEX-NOINDEX vigila una regla concreta.
El resumen enseña tres ejemplos por grupo. Para la lista entera, nombra una regla o un tipo de cambio:
crawlforge diff antes.sqlite despues.sqlite --rule HTTP-404-INTERNAL # todos los nuevos y resueltos
crawlforge diff antes.sqlite despues.sqlite --change url_removed # todas las URLs que se fueron
Los tipos son url_added, url_removed, status_changed, title_changed,
meta_description_changed, canonical_changed, indexability_lost, indexability_gained,
issue_appeared, issue_resolved, robots_txt_changed y sitemap_changed.
Para conservar un diff, guárdalo con --out cambios.sqlite. Se vuelve a abrir con el mismo comando
y solo ese fichero: el resumen sale como era, en el idioma que pidas, y --rule y --change
también funcionan sobre él:
crawlforge diff cambios.sqlite --lang es
crawlforge diff cambios.sqlite --change status_changed
Un diff guardado solo se lee: --fail-on es para el momento de comparar, no para después.
Un sitio protegido con contraseña (staging)
CRAWLFORGE_AUTH='usuario:contraseña' crawlforge crawl https://pre.cliente.es/
También se acepta en la URL como atajo, aunque así queda en el historial del shell:
crawlforge crawl https://usuario:contraseña@pre.cliente.es/
En los dos casos, la credencial no se guarda en el fichero de rastreo y no viaja a ningún host
que no sea el de la semilla, ni siquiera si el sitio enlaza a otro dominio. Por eso resume
también necesita la variable: el fichero no la lleva dentro a propósito.
Se aplica también al robots.txt y a los sitemaps — si no, un staging protegido devolvería 401 al
pedirlos y el rastreo se comportaría de forma rara sin decir por qué.
Una lista exacta de URLs
crawlforge list urls.txt
Un fichero con una URL por línea. Sirve para revisar un conjunto concreto —las 40 landings de una campaña— y es también el modo que hace justa una comparación con otra herramienta: las dos reciben exactamente el mismo conjunto.
Una lista puede mezclar sitios. Se audita cada sitio que aparece en el fichero —host y puerto—, así que en una misma lista caben páginas de todos los blogs de una cartera. Una página de cualquiera de ellos que está enlazada pero no en la lista se registra sin pedirse, igual que si fuera del primero, y una página rota de cualquiera de ellos es un 404 interno.
Un enlace de un sitio de la lista a otro sigue saliendo del sitio de la página: no cuenta entre
sus enlaces internos, y un nofollow en él no es INDEX-NOFOLLOW-INTERNAL. Los dos sitios son
tuyos, pero para un buscador son dos sitios.
La credencial de CRAWLFORGE_AUTH sigue saliendo de la primera URL: solo se manda a su host. El
informe nombra todos los sitios en el título (Auditoría de 2 sitios: …), y el panel de cartera
también.
Se ha cortado el rastreo
crawlforge resume crawl-tumedio-com.sqlite
Sigue exactamente donde se quedó, con la configuración guardada en el propio fichero. No repite lo ya rastreado. Un rastreo terminado no se puede reanudar: para eso se relanza.
Con una excepción: un rastreo que el sitio frenó. Si hay páginas que tras los reintentos
siguen respondiendo 429 Too Many Requests (un Cloudflare o un cortafuegos pidiendo al rastreador
que vaya más despacio), no se dan por rotas. Quedan pendientes, el resumen dice cuántas y las
reglas que necesitan el sitio entero no se evalúan. resume sobre ese fichero terminado pide solo
esas páginas, cuando el límite se haya levantado. Si se repite, rastrea con menos --concurrency o
deja pasar el user-agent de CrawlForge en el cortafuegos del sitio. Cuando el 429 dice cuánto
esperar (Retry-After), el rastreador espera eso antes de reintentar y mientras tanto no lanza
ninguna petición nueva a ese host; si pide más de dos minutos, la página queda pendiente directamente, sin reintentos.
Rastreos que se repiten: guarda la configuración
cp docs/crawl-config.example.yaml cliente.yaml # y edítalo
crawlforge crawl https://cliente.com/ --config cliente.yaml
El fichero describe el sitio, la línea de comandos describe la ejecución: los flags ganan sobre el YAML. Un campo mal escrito es un error, no una opción ignorada en silencio.
Que el editor lo revise mientras escribes. Las claves, sus tipos y valores por defecto, y todos
los IDs de regla y severidades que acepta rules: se publican como JSON Schema,
docs/crawl-config.schema.json. La primera línea del ejemplo apunta
a él a un servidor de lenguaje YAML (VS Code con la extensión YAML de Red Hat, Zed, Neovim,
JetBrains), así que una copia suya ya completa las claves y subraya las erratas:
# yaml-language-server: $schema=https://raw.githubusercontent.com/dcarrero/crawlforge/main/docs/crawl-config.schema.json
crawlforge config schema imprime el esquema del binario que tienes, para una copia sin conexión
o para dárselo a un asistente que escriba el fichero por ti: crawlforge config schema > crawl-config.schema.json y apunta la línea a esa ruta. El esquema escribe los IDs de regla en
mayúsculas; CrawlForge también los acepta en minúsculas.
Cada sitio con su criterio: desactivar reglas, cambiar severidades
No todos los clientes tienen el mismo listón. Un blog cuya plantilla escribe meta descriptions
largas a propósito no necesita oírlo cada semana, y un enlace externo roto puede ser low en un
sitio y high en otro. Se dice en el YAML del sitio:
rules:
disable: [META-DESC-TOO-LONG, CONTENT-H1-MULTIPLE]
severity:
HTTP-404-EXTERNAL: low
El rastreo sigue evaluando todas las reglas y guardando todos los hallazgos con la severidad
del catálogo. El bloque se guarda dentro del fichero de rastreo, y report, inspect, export,
diff y portfolio lo aplican al leerlo. Cambiar de idea no cuesta nada: se edita el YAML y se
vuelve a leer el mismo fichero con --config, sin rastrear otra vez.
crawlforge crawl https://cliente.com/ --config cliente.yaml # guarda el bloque
crawlforge report cliente.sqlite # lo aplica
crawlforge report cliente.sqlite --config otro.yaml # aplica el de otro.yaml
--configen un comando de lectura sustituye al bloque guardado en esa ejecución. Solo se usarules:; el resto del fichero se sigue comprobando por si hay erratas. Un fichero sinrules:enseña todos los hallazgos, y así se ve lo que la configuración oculta.- Toda salida que aplica una configuración lo dice: «Configuración de reglas (guardada en el
fichero de rastreo): 2 reglas desactivadas, 1 severidad cambiada». La hoja
Summarydel XLSX la detalla y el export a CSV la imprime en el terminal. Los exports dejan fuera los hallazgos de las reglas desactivadas y escriben la severidad cambiada. diffevalúa los dos rastreos con la misma configuración: la de--configsi se da, y si no la guardada en el rastreo posterior. De lo contrario, desactivar una regla entre dos rastreos haría pasar sus hallazgos por «resueltos». Si los dos ficheros guardan configuraciones distintas, el diff lo dice.--fail-onjuzga la severidad cambiada.portfoliolee cada sitio con su propia configuración guardada y nombra los sitios que tienen una: un sitio que desactivó una regla no es un sitio sin ese problema.- Un ID de regla o una severidad desconocidos son un error que los nombra. Los IDs se reconocen sin distinguir mayúsculas.
Ver qué comprueba la herramienta
crawlforge rules --lang es # el catálogo entero, en tabla
crawlforge rules INDEX-ORPHAN-PAGE # la ficha de una regla concreta, por su ID
crawlforge rules --lang es --category canonical
crawlforge rules --lang es --detail # con la explicación completa de cada una
crawlforge rules --format json # el catálogo entero como datos, en todos los idiomas
El JSON es para lo que consuma el catálogo como datos — un script de CI que comprueba que un
ID de regla sigue existiendo, o una página generada del catálogo en vez de copiarlo. Lleva
siempre todos los idiomas traducidos (name.en, name.es…; inglés y español siempre, los demás
cuando estén traducidos), y su sobre dice la versión del catálogo y el número de reglas.
3. Cómo se lee el resultado
En el terminal
report sin más da el resumen: cuántas URLs, cuántas indexables, y los hallazgos agrupados por
severidad. Es para responder «¿cómo está esto?» en diez segundos.
El XLSX
crawlforge export crawl.sqlite --format xlsx --out auditoria.xlsx
Catorce hojas, cada una con la cabecera congelada y el autofiltro puesto. Los códigos de estado son números de verdad, así que un filtro «mayor que 399» funciona como esperas. Una celda de estado vacía es una URL que se registró y nunca se pidió: un enlace interno fuera del alcance del rastreo, o uno externo con la comprobación apagada.
Está comprobado que abre limpio en Microsoft Excel 16, sin aviso de reparación.
El SQLite, si quieres ir más allá
Es la ventaja de que el formato no sea propietario. Cualquier pregunta que el informe no responda, la responde SQL.
Las tres tablas que se usan el 90% de las veces:
| Tabla | Qué guarda | Clave |
|---|---|---|
urls |
Toda URL vista: url, status_code, depth, content_type, response_time_ms |
id |
pages |
Lo extraído del HTML: title, h1, word_count, canonical, is_indexable |
url_id → urls.id |
issues |
Un hallazgo por fila: rule_id, severity |
url_id → urls.id |
# Las URLs que fallan
sqlite3 crawl-cliente-com.sqlite \
"SELECT url, status_code FROM urls WHERE status_code >= 400 ORDER BY status_code DESC LIMIT 20;"
# Qué páginas dispararon una regla concreta
sqlite3 crawl-cliente-com.sqlite \
"SELECT u.url FROM issues i JOIN urls u ON u.id = i.url_id
WHERE i.rule_id = 'CONTENT-H1-MISSING' LIMIT 20;"
# Las páginas más lentas
sqlite3 crawl-cliente-com.sqlite \
"SELECT url, response_time_ms FROM urls ORDER BY response_time_ms DESC LIMIT 10;"
Hay vistas ya preparadas para las preguntas habituales: v_orphans, v_broken_links,
v_indexable_pages y v_issue_summary.
v_broken_links sigue además las redirecciones hasta donde acaban, así que un enlace a tu propio
/go/producto que redirige a una tienda que devuelve 404 sale como roto. En esas filas via es la
URL que se enlazó de verdad, la que hay que reescribir, y hops cuántos saltos hicieron falta; las
dos van a NULL cuando el enlace apunta directamente a lo roto.
Dos avisos que ahorran un rato: la columna es status_code, no status, y está a NULL en
toda URL que se registró sin pedirse: un enlace interno al que el rastreo no llegó, o uno externo
si va --no-external-check.
3.bis Cómo se lee un informe
El resumen es una línea por regla, ordenado por severidad. Tres cosas que conviene saber para interpretarlo:
La cuota del sitio
medium META-TITLE-TOO-LONG 173,654 (80% of the site)
Cuando una regla afecta al 40% o más de las páginas, la línea añade su cuota. Es la diferencia entre una lista de páginas que arreglar una a una y un problema sistémico: 2.193 imágenes rotas son 2.193 arreglos; 173.654 títulos largos al 80% del sitio son una plantilla o un patrón de publicación, y se arregla en un sitio.
Los problemas de plantilla
high ASSET-IMG-EMPTY-ALT-LINK 13 template issues (567 pages) + 90 more findings
e.g. https://ejemplo.com/a · https://ejemplo.com/b
Cuando el mismo defecto aparece por la misma causa en muchas páginas —el logo de la cabecera, un
enlace del pie, el <h4> de la firma del autor— se cuenta como un problema, con ejemplos. Las
filas siguen todas en el fichero: lo que cambia es el recuento del informe, no lo que se guarda.
Ver todas las URLs de una regla
El resumen nunca enumera. Para la lista completa:
crawlforge report crawl.sqlite --rule HTTP-404-INTERNAL
Sale ordenada, con los grupos de plantilla primero y su causa al lado. Es el comando que sustituye al «… y 26 más» que no llevaba a ninguna parte.
La ficha de una URL: ¿quién enlaza aquí?
La pregunta que más se repite en una auditoría tiene su propio comando:
crawlforge inspect crawl.sqlite 'https://cliente.com/pagina/'
Vale también la ruta sola (/pagina/), el dominio sin esquema, y con o sin la barra final. Si te
equivocas, el error sugiere las URLs más parecidas del fichero en vez de decir solo «no está».
La ficha enseña el estado HTTP, lo extraído (título, meta description, H1, palabras, canonical,
indexabilidad), los hallazgos de esa URL, su cadena de redirecciones si redirige, sus imágenes, y
—la sección estrella— quién enlaza a esa página: deduplicado por página que enlaza, con su
texto de ancla, si es nofollow y desde qué región (los enlaces de contenido primero, el ruido de
nav y footer después). Salida real, recortada:
$ crawlforge inspect crawl-tumedio-com.sqlite '/nueva-piscina-municipal-abre-en-junio'
── Inlinks (24) ─────────────────────────────
By region: unknown 13 · main 11 · 0 nofollow
Linking pages, content links first:
main "la nueva piscina abre en junio" — https://tumedio.com/obras-del-polideportivo-terminadas/
main "la piscina municipal" — https://tumedio.com/presupuesto-municipal-2026/
unknown (no anchor text) ×4 — https://tumedio.com/tag/deportes/
── Outlinks (156: 108 internal, 48 external) ─
200 https://tumedio.com/quienes-somos/ "¿Quiénes somos?"
Los salientes enseñan el código de estado del destino con los rotos primero: la ficha de una página es también su triaje de enlaces rotos. Y si la URL inspeccionada es una imagen, la ficha dice en qué páginas se usa — la dirección contraria a la sección de imágenes.
Cada lista corta en 20 filas y el corte dice el comando exacto que la completa (--limit all;
también acepta un número). --lang es la traduce, y --format md con --out ficha.md produce
una ficha para pegar en un ticket:
crawlforge inspect crawl.sqlite '/pagina/' --format md --out ficha.md
3.ter Escenarios completos
Auditoría de un cliente, de principio a fin
crawlforge crawl https://cliente.com/
crawlforge report crawl-cliente-com.sqlite --lang es # ¿qué tiene?
crawlforge report crawl-cliente-com.sqlite --rule CONTENT-H1-MISSING # ¿dónde?
crawlforge inspect crawl-cliente-com.sqlite '/esa-pagina/' --lang es # ¿quién enlaza aquí?
crawlforge export crawl-cliente-com.sqlite --format xlsx --out cliente.xlsx
crawlforge report crawl-cliente-com.sqlite --format html --out cliente.html --lang es
El .xlsx es para trabajar; el .html es para enviar.
Vigilar un despliegue
crawlforge crawl https://cliente.com/ # antes de publicar
# … se publica …
crawlforge crawl https://cliente.com/ # el anterior pasa a .prev.sqlite
crawlforge diff crawl-cliente-com.prev.sqlite crawl-cliente-com.sqlite --lang es
Y en un pipeline de CI, sobre la carpeta compilada y sin red:
crawlforge audit ./dist --base https://cliente.com/ --out nuevo.sqlite
crawlforge diff referencia.sqlite nuevo.sqlite --fail-on high || exit 1
Revisar una cartera de sitios
for s in blog1.com blog2.com blog3.com; do
crawlforge crawl "https://$s/" --out "cartera/$s.sqlite"
done
crawlforge portfolio ./cartera --lang es
Un solo panel sobre todos los ficheros: qué cambió desde el rastreo anterior de cada sitio, qué reglas fallan en cuántos sitios, y una línea por sitio. Entero en §3.quater.
Un conjunto concreto de URLs
printf '%s\n' https://cliente.com/landing-a https://cliente.com/landing-b > urls.txt
crawlforge list urls.txt --lang es
3.quater La cartera: muchos sitios a la vez
Una auditoría suelta es una foto. Quien lleva muchos sitios necesita otras dos respuestas:
qué se rompió desde la semana pasada y qué falla en todos a la vez. Eso es
portfolio:
crawlforge portfolio ./rastreos/ # un directorio se recorre buscando *.sqlite
crawlforge portfolio a.sqlite b.sqlite c.sqlite
Los .prev.sqlite que hay junto a tus rastreos no cuentan como sitios: cada uno es el
«antes» del rastreo de al lado, y el panel compara la pareja solo. Es el mismo fichero que
usa diff, producido de la misma manera: repitiendo el rastreo sobre el mismo fichero de
salida.
El panel cuenta sitios, no ficheros. Una lista list que auditó varios sitios ocupa una sola
fila, con todos ellos en la etiqueta, pero suma cada uno de sus sitios al recuento de la cabecera,
al «salta en N de M sitios» (sus hallazgos se reparten según el sitio de su URL) y al tope de
sitios del nivel. Hasta la 0.15.0 contaba como uno, y una lista con cincuenta dominios pasaba por
un solo sitio.
Salida real, recortada (una cartera de prueba de cinco sitios; dos ficheros los rastreó una versión anterior, un rastreo quedó truncado y otro es de modo lista):
$ crawlforge portfolio ./cartera --lang es
── Panel de cartera ─────────────────────────
5 sitios · rastreos del 2026-08-04 al 2026-08-04
── Avisos ───────────────────────────────────
AVISO No todos los sitios se rastrearon con el mismo catálogo de reglas (0.4.0,
0.6.2). Una regla puede faltar en un sitio porque no existía cuando se rastreó.
── Qué cambió ───────────────────────────────
1 de 5 sitios tiene un rastreo anterior (.prev.sqlite) con el que comparar.
Hallazgos nuevos críticos y altos:
https://alpha.example/
crítico HTTP-404-INTERNAL 2
https://alpha.example/p/000005/
https://alpha.example/p/000006/
El resto, sitio a sitio:
https://alpha.example/
Hallazgos resueltos 2 · Códigos de estado que empeoran 2
── Qué falla en toda la cartera ─────────────
Una regla que salta en la mayoría de los sitios rara vez es contenido: suele ser una
plantilla o un plugin compartido — un arreglo que sirve para todos.
medio CANON-CROSS-DOMAIN 3 de 5 sitios
crítico HTTP-NO-HTTPS 2 de 5 sitios
medio INDEX-DEEP-PAGE 1 de 5 sitios (2 no concluyentes)
── La cartera de un vistazo ─────────────────
URLs index. crit high med low info rastreado sitio
240 0 2 0 118 0 0 2026-08-04 https://alpha.example/
8 0 1 1 7 0 0 2026-08-04 http://127.0.0.1:8912/ (truncado)
Tres cosas de esa salida son deliberadas, y son las que hacen fiable el panel:
- «1 de 5 sitios (2 no concluyentes)» — un rastreo truncado o de modo lista nunca evaluó las reglas que necesitan el grafo de enlaces completo, así que para esas reglas el panel separa tres estados: dispara, no dispara, y no se pudo evaluar. Una regla que no aparece en un sitio truncado no es una regla que ahí pase.
- El aviso del catálogo va arriba. Ficheros rastreados con catálogos de reglas distintos no se comparan en silencio: una regla puede «faltar» en un sitio porque aún no existía.
- El rango de fechas se dice siempre, y si entre el rastreo más viejo y el más nuevo hay más de una semana el panel lo avisa: eso no es una foto de la cartera, y «qué cambió» cubriría un periodo distinto en cada sitio.
Un fichero que no se puede abrir —no es un rastreo, es una base de otro programa, tiene un esquema más nuevo que el binario— sale en «Ficheros apartados» con su motivo, y el resto del panel se produce igual. Un fichero malo no te cuesta los otros once.
Lo demás funciona como report: --lang es traduce el panel, y --format md o
--format html con --out producen un fichero para pegar en un ticket o enviar:
crawlforge portfolio ./cartera --format html --out panel.html --lang es
El panel no es del nivel gratuito. La CLI corre por defecto como el nivel más alto; solo
importa si defines CRAWLFORGE_TIER (ver §5).
4. Lo que hoy no hace
Dicho por delante, para que no pierdas tiempo buscándolo:
- No renderiza JavaScript. Un sitio cuyo contenido se monta en el navegador se verá vacío. Está previsto.
- No sigue los sitios externos. De los enlaces salientes se comprueba el estado —que es lo que
hace saltar
HTTP-404-EXTERNAL, yHTTP-EXTERNAL-UNVERIFIABLEcuando el otro sitio rechaza la comprobación con un 401, 403 o 429—, pero de otro dominio no se parsea ni se rastrea nada. No hay flag--follow-external: rastrear entero un sitio ajeno no es algo que la herramienta ofrezca desde la línea de comandos. La clavefollow_externalexiste en el fichero de configuración y sigue apagada por defecto; una reanudación ignora lo que el fichero diga de ella, igual que ignora unignore_robotsguardado. - No hay interfaz gráfica todavía.
- No hay programación de rastreos. El panel de cartera (§3.quater) lee los ficheros que ya tienes; producirlos a un ritmo sigue siendo trabajo de tu cron.
HTTP-TEMP-REDIRECTno existe todavía: necesita un histórico de rastreos que aún no existe.
Están implementadas todas las reglas del catálogo salvo HTTP-TEMP-REDIRECT; crawlforge rules lista las que trae tu build.
5. Cuando algo va mal
| Síntoma | Qué pasa |
|---|---|
| El rastreo acaba con muchas menos URLs de las que esperas | Algo lo cortó: --max-urls, --max-depth, --max-duration, o el tope de 1.000 del nivel gratuito si está puesto CRAWLFORGE_TIER=free. El informe dice que el rastreo quedó truncado y por qué límite. |
Un report menciona hallazgos «no evaluados» |
El rastreo se truncó y las reglas que necesitan el grafo completo se han silenciado a propósito. |
| El sitio devuelve 429 o 503 | Baja --concurrency. La herramienta ya reduce a la mitad su concurrencia en ese host tras tres 429, 503, conexiones cortadas o timeouts seguidos, espera lo que pida un Retry-After (hasta dos minutos) antes de reintentar y respeta el Crawl-delay del robots.txt, pero un WAF puede ser más estricto que todo eso. Si redujo la concurrencia, el resumen del rastreo lo dice y cuántas veces. |
«no such file» al hacer diff |
Falta el .prev.sqlite: solo aparece al repetir un rastreo sobre el mismo fichero de salida. |
| El programa parece colgado tras rastrear | Está en la pasada final: enlaces entrantes y reglas de conjunto. Dice por qué regla va (final pass · rule 7/29 · …). En sitios grandes tarda minutos. |
| Un rastreo antiguo no se puede reanudar | Solo se rechaza si el fichero es más nuevo que el programa, o si le falta cruzar una migración que cambia lo que el motor escribe. Se sigue abriendo con report, export y diff. |
Aparecen .sqlite-wal y .sqlite-shm al lado |
El rastreo no cerró limpiamente. No copies solo el .sqlite: te faltarían datos. Vuelve a abrirlo con crawlforge report para que los consolide. |
Los errores dicen qué fichero falta y qué comando lo genera. Si alguno no lo dice, es un fallo del producto y merece anotarse.
6. Referencia rápida
crawlforge crawl <URL> # rastrear por HTTP
crawlforge audit <DIR> --base <URL> # auditar una carpeta compilada
crawlforge list <FICHERO> # una lista exacta de URLs
crawlforge resume <FICHERO> # continuar un rastreo cortado
crawlforge report <FICHERO> # resumen, o --format md|html
crawlforge export <FICHERO> --format xlsx --out a.xlsx
crawlforge diff <ANTES> <DESPUES> [--fail-on high] [--out d.sqlite]
crawlforge diff <DIFF> [--rule ID | --change TIPO] # abrir un diff guardado
crawlforge portfolio <RUTA>... [--format md|html --out f] # panel sobre muchos rastreos
crawlforge rules [--category X] [--detail] [--format json]
crawlforge config schema # JSON Schema del YAML de --config
# report, inspect, export, diff y portfolio aceptan --config <YAML> para aplicar su `rules:`
Cualquiera de ellos con --help da la lista completa de opciones.