Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
wxpath — wxpath - rastreo web declarativo con XPath; un Lenguaje de Consulta Web (WQL) | Kitploit
Herramientas/GitHubGitHub/rodricios/wxpath
OSINT (Inteligencia de Fuentes Abiertas)ReconocimientoExfiltración de DatosRecopilación de InformaciónSeguridad WebCrawler
GitHubrodricios/wxpath

wxpath

wxpath - rastreo web declarativo con XPath; un Lenguaje de Consulta Web (WQL)

Ver Repositorio
11162hace 2 mesesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

wxpath - recorrido declarativo de grafos web con XPath

Python 3.10+ Documentation Status

NUEVO: TUI – Interfaz de terminal interactiva (impulsada por Textual) para probar expresiones wxpath y exportar datos.

Captura de pantalla de la demostración de Wxpath TUI

Instalación

Requiere Python 3.10+.

root@kitploit:~
pip install wxpath
# For TUI support:
pip install "wxpath[tui]"
# Immediately launch the TUI via uv:
uvx --from "wxpath[tui]" wxpath-tui

¿Qué es wxpath?

wxpath es un rastreador web declarativo donde el recorrido se expresa directamente en XPath. En lugar de escribir bucles de rastreo imperativos, wxpath te permite describir qué seguir y qué extraer en una sola expresión. wxpath ejecuta esa expresión de forma concurrente, en un orden similar a primero en anchura, y transmite los resultados a medida que se descubren.

Esta expresión obtiene una página, extrae enlaces y los transmite concurrentemente, sin necesidad de un bucle de rastreo:

root@kitploit:~
import wxpath

expr = "url('https://quotes.toscrape.com')//a/@href"

for link in wxpath.wxpath_async_blocking_iter(expr):
    print(link)

Al introducir el operador url(...) y la sintaxis ///, el motor de wxpath puede realizar rastreo y extracción web recursivos (o paginados):

root@kitploit:~
import wxpath

path_expr = """
url('https://quotes.toscrape.com')
  ///url(//a/@href)
    //a/@href
"""

for item in wxpath.wxpath_async_blocking_iter(path_expr, max_depth=1):
    print(item)

¿Por qué wxpath?

La mayoría de los raspadores web te obligan a escribir primero el flujo de control del rastreo y luego la extracción.

wxpath unifica esos dos pasos en uno:

  • Describes el recorrido de forma declarativa
  • La extracción se expresa en línea
  • El motor maneja la planificación, concurrencia y deduplicación

Salida lista para RAG

Extrae jerarquías JSON limpias y estructuradas directamente del grafo: alimenta tus LLMs con señal, no con ruido. Consulta Integración con LangChain para más detalles.

Determinista

wxpath es determinista (léase: no impulsado por LLMs). Aunque no podemos garantizar que la red sea estable, podemos garantizar que el recorrido lo es.

Documentación (en proceso)

La documentación ya está disponible aquí.

Contenidos

  • Ejemplo: Grafo de conocimiento
  • Diseño del lenguaje
  • url(...) y ///url(...) explicados
  • Flujo general
  • Rastreo asíncrono
  • Rastreo educado
  • Tipos de salida
  • XPath 3.1
  • Barra de progreso
  • CLI
  • TUI
  • Persistencia y caché
  • Ajustes
  • Hooks (Experimental)
  • Instalación
  • Más ejemplos
  • Comparaciones
  • Avanzado: Configuración del motor y rastreador
  • Filosofía del proyecto
  • Advertencias
  • Soporte comercial / consultoría
  • Versionado
  • Licencia

Ejemplo

root@kitploit:~
import wxpath
from wxpath.settings import CRAWLER_SETTINGS

# Custom headers for politeness; necessary for some sites (e.g., Wikipedia)
CRAWLER_SETTINGS.headers = {'User-Agent': 'my-app/0.4.0 (contact: [email protected])'}

# Crawl, extract fields, build a knowledge graph
path_expr = """
url('https://en.wikipedia.org/wiki/Expression_language')
  ///url(
        //main//a/@href[
            starts-with(., '/wiki/') and not(contains(., ':'))
        ]
    )
    /map{
        'title': (//span[contains(@class, "mw-page-title-main")]/text())[1] ! string(.),
        'url': string(base-uri(.)),
        'short_description': //div[contains(@class, 'shortdescription')]/text() ! string(.),
        'forward_links': //div[@id="mw-content-text"]//a/@href ! string(.)
    }
"""

for item in wxpath.wxpath_async_blocking_iter(path_expr, max_depth=1):
    print(item)

Nota: Algunos sitios (incluyendo Wikipedia) pueden bloquear solicitudes sin las cabeceras adecuadas.
Consulta Avanzado: Configuración del motor y rastreador para establecer un User-Agent personalizado.

La expresión anterior hace lo siguiente:

  1. Comienza en la URL especificada, https://en.wikipedia.org/wiki/Expression_language.
  2. Filtra enlaces en la sección <main> que empiezan con /wiki/ y no contienen dos puntos (:).
  3. Para cada enlace encontrado,
    • sigue el enlace y extrae el título, la URL y la descripción corta de la página.
    • repite el paso 2 hasta alcanzar la profundidad máxima.
  4. Transmite los datos extraídos a medida que se descubren.

url(...) y ///url(...) explicados

  • url(...) es un operador personalizado que obtiene el contenido de la URL especificada por el usuario o generada internamente y lo devuelve como un lxml.html.HtmlElement para su posterior procesamiento con XPath.
  • ///url(...) indica un rastreo profundo. Le dice al motor que continúe siguiendo enlaces hasta el max_depth especificado. A diferencia de saltos repetidos con url(), permite que una sola expresión describa una exploración más profunda del grafo. ADVERTENCIA: Úsalo con cuidado y con restricciones (mediante max_depth o predicados XPath) para evitar explosión del recorrido.

Diseño del lenguaje

Consulta DESIGN.md para más detalles sobre el diseño del lenguaje. Allí verás los conceptos centrales y el diseño del lenguaje desde cero.

Flujo general

wxpath evalúa una expresión como una lista de pasos de recorrido y extracción (internamente llamados Segment).

url(...) crea tareas de rastreo, ya sea estáticamente (mediante una URL fija) o dinámicamente (mediante una URL derivada de la expresión XPath). Las URLs se deduplican globalmente, con el mejor esfuerzo, no por profundidad.

Los segmentos XPath operan sobre documentos obtenidos (a través de las operaciones url(...) inmediatamente anteriores).

///url(...) indica rastreo profundo: procede en orden similar a primero en anchura hasta max_depth.

Los resultados se entregan tan pronto como están listos.

Rastreo asíncrono

wxpath es ante todo asyncio/aiohttp, proporcionando una API asíncrona para rastrear y extraer datos.

root@kitploit:~
import asyncio
from wxpath import wxpath_async

items = []

async def main():
    path_expr = "url('https://en.wikipedia.org/wiki/Expression_language')///url(//@href[starts-with(., '/wiki/')])//a/@href"
    async for item in wxpath_async(path_expr, max_depth=1):
        items.append(item)

asyncio.run(main())

Peticiones concurrentes bloqueantes

wxpath también proporciona una API asíncrona-dentro-de-síncrona, que permite rastrear varias páginas concurrentemente manteniendo la simplicidad del código síncrono. Esto es especialmente útil para rastreos en entornos estrictamente síncronos (es decir, fuera de un bucle de eventos asyncio) donde el rendimiento es importante.

root@kitploit:~
from wxpath import wxpath_async_blocking_iter

path_expr = "url('https://en.wikipedia.org/wiki/Expression_language')///url(//@href[starts-with(., '/wiki/')])//a/@href"
items = list(wxpath_async_blocking_iter(path_expr, max_depth=1))

Rastreo educado

wxpath respeta robots.txt por defecto mediante el constructor WXPathEngine(..., robotstxt=True).

Tipos de salida

La API de Python de wxpath devuelve objetos estructurados.

Dependiendo de la expresión, los resultados pueden incluir:

  • objetos lxml.* y lxml.html.*
  • objetos elementpath.datatypes.* (para características de XPath 3.1)
  • WxStr (valores de cadena con procedencia)
  • diccionarios / mapas
  • listas u otros valores nativos de XPath

La CLI aplana estos objetos en JSON simple para su visualización. La API de Python conserva la estructura por defecto.

XPath 3.1 por defecto

wxpath utiliza la librería elementpath para proporcionar soporte para XPath 3.1, permitiendo características avanzadas de XPath como mapas, arrays y más. Esto permite escribir consultas XPath más potentes.

root@kitploit:~
path_expr = """
    url('https://en.wikipedia.org/wiki/Expression_language')
    ///url(//div[@id='mw-content-text']//a/@href)
    /map{ 
        'title':(//span[contains(@class, "mw-page-title-main")]/text())[1], 
        'short_description':(//div[contains(@class, "shortdescription")]/text())[1],
        'url'://link[@rel='canonical']/@href[1]
    }
"""
# [...
# {'title': 'Computer language',
# 'short_description': 'Formal language for communicating with a computer',
# 'url': 'https://en.wikipedia.org/wiki/Computer_language'},
# {'title': 'Machine-readable medium and data',
# 'short_description': 'Medium capable of storing data in a format readable by a machine',
# 'url': 'https://en.wikipedia.org/wiki/Machine-readable_medium_and_data'},
# {'title': 'Domain knowledge',
# 'short_description': 'Specialist knowledge within a specific field',
# 'url': 'https://en.wikipedia.org/wiki/Domain_knowledge'},
# ...]

Barra de progreso

wxpath proporciona una barra de progreso (mediante tqdm) para seguir el avance del rastreo. Es especialmente útil para rastreos de larga duración.

Actívala configurando engine.run(..., progress=True), o pasando progress=True a cualquiera de las funciones wxpath_async*(...).

root@kitploit:~
items = wxpath.wxpath_async_blocking("...", progress=True)
> 100%|██████████████████████████████████████████████████████████▎| 469/471 [00:05<00:00, 72.00it/s, depth=2, yielded=457]

CLI

wxpath proporciona una interfaz de línea de comandos (CLI) para experimentar rápidamente y ejecutar expresiones wxpath directamente desde el terminal.

El siguiente ejemplo demuestra cómo rastrear Wikipedia comenzando desde la página "Expression language", extraer enlaces a otras páginas wiki y recuperar campos específicos de cada página enlazada.

NOTA: Debido a la naturaleza cambiante del contenido web, la salida puede variar con el tiempo.

root@kitploit:~
> wxpath --depth 1 \
    --header "User-Agent: my-app/0.1 (contact: [email protected])" \
    "url('https://en.wikipedia.org/wiki/Expression_language') \
    ///url(//div[@id='mw-content-text']//a/@href[starts-with(., '/wiki/') \
        and not(matches(@href, '^(?:/wiki/)?(?:Wikipedia|File|Template|Special|Template_talk|Help):'))]) \
    /map{ \
        'title':(//span[contains(@class, 'mw-page-title-main')]/text())[1], \
        'short_description':(//div[contains(@class, 'shortdescription')]/text())[1], \
        'url':string(base-uri(.)), \
        'backlink':wx:backlink(.), \
        'depth':wx:depth(.) \
        }"

{"title": "Computer language", "short_description": "Formal language for communicating with a computer", "url": "https://en.wikipedia.org/wiki/Computer_language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Machine-readable medium and data", "short_description": "Medium capable of storing data in a format readable by a machine", "url": "https://en.wikipedia.org/wiki/Machine_readable", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Domain knowledge", "short_description": "Specialist knowledge within a specific field", "url": "https://en.wikipedia.org/wiki/Domain_knowledge", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Advanced Boolean Expression Language", "short_description": "Hardware description language and software", "url": "https://en.wikipedia.org/wiki/Advanced_Boolean_Expression_Language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Data Analysis Expressions", "short_description": "Formula and data query language", "url": "https://en.wikipedia.org/wiki/Data_Analysis_Expressions", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Jakarta Expression Language", "short_description": "Computer programming language", "url": "https://en.wikipedia.org/wiki/Jakarta_Expression_Language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Rights Expression Language", "short_description": [], "url": "https://en.wikipedia.org/wiki/Rights_Expression_Language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Computer science", "short_description": "Study of computation", "url": "https://en.wikipedia.org/wiki/Computer_science", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}

Opciones de línea de comandos:

root@kitploit:~
--depth                <depth>       Profundidad máxima de rastreo
--verbose              [true|false]  Proporciona información superficial de la CLI
--debug                [true|false]  Proporciona salida detallada del tiempo de ejecución e información
--concurrency          <concurrency> Número de descargas concurrentes
--concurrency-per-host <concurrency> Número de descargas concurrentes por host
--header               "Key:Value"   Añade una cabecera personalizada (ej., 'Key:Value'). Se puede usar varias veces.
--respect-robots       [true|false] (Por defecto: True) Respeta robots.txt
--cache                [true|false] (Por defecto: False) Persiste los resultados del rastreo en una base de datos local

TUI

wxpath proporciona una interfaz de terminal (TUI) para pruebas interactivas de expresiones y extracción de datos.

Consulta Inicio rápido de TUI para más detalles.

Persistencia y caché

wxpath opcionalmente persiste los resultados del rastreo en una base de datos local. Esto es especialmente útil cuando se rastrea un gran número de URLs y se decide pausar el rastreo, cambiar expresiones de extracción, o necesitar reiniciarlo.

wxpath soporta dos motores: sqlite y redis. SQLite es ideal para rastreos a pequeña escala con un solo trabajador (es decir, engine.crawler.concurrency == 1). Redis es ideal para rastreos a gran escala con múltiples trabajadores. Recibirás una advertencia si min(engine.crawler.concurrency, engine.crawler.per_host) > 1 al usar el motor sqlite.

Para usarlo, debes instalar la dependencia opcional correspondiente:

root@kitploit:~
pip install wxpath[cache-sqlite]
pip install wxpath[cache-redis]

Una vez instalada la dependencia, debes habilitar la caché:

root@kitploit:~
from wxpath.settings import SETTINGS

# To enable caching; sqlite is the default
SETTINGS.http.client.cache.enabled = True

# For redis backend
SETTINGS.http.client.cache.enabled = True
SETTINGS.http.client.cache.backend = "redis"
SETTINGS.http.client.cache.redis.address = "redis://localhost:6379/0"

# Run wxpath as usual
items = list(wxpath_async_blocking_iter('...', max_depth=1, engine=engine))

Ajustes

Consulta settings.py para más detalles sobre los ajustes.

Hooks (Experimental)

wxpath soporta un sistema de hooks conectables que permite modificar el comportamiento de rastreo y extracción. Puedes registrar hooks para preprocesar URLs, postprocesar HTML, filtrar valores extraídos y más. Los hooks se ejecutarán en el orden en que se registren. Los hooks pueden afectar al rendimiento.

root@kitploit:~

from wxpath import hooks

@hooks.register
class OnlyEnglish:
    def post_parse(self, ctx, elem):
        lang = elem.xpath('string(/html/@lang)').lower()[:2]
        return elem if lang in ("en", "") else None

Uso asíncrono

NOTA: Los hooks pueden ser síncronos o asíncronos, pero todos los hooks en un proyecto deben seguir el mismo estilo. Mezclar hooks síncronos y asíncronos no está soportado y puede causar comportamientos inesperados.

root@kitploit:~

from wxpath import hooks

@hooks.register
class OnlyEnglish:
    async def post_parse(self, ctx, elem):
        lang = elem.xpath('string(/html/@lang)').lower()[:2]
        return elem if lang in ("en", "") else None

Hooks predefinidos

JSONLWriter (alias NDJSONWriter) es un hook integrado que escribe los datos extraídos en un archivo JSON delimitado por nuevas líneas. Es útil para almacenar resultados en un formato estructurado que puede procesarse fácilmente después.

root@kitploit:~
from wxpath import hooks
hooks.register(hooks.JSONLWriter)

Instalación

Requiere Python 3.10+.

root@kitploit:~
pip install wxpath

Para persistencia/caché, wxpath soporta los siguientes motores:

root@kitploit:~
pip install wxpath[cache-sqlite]
pip install wxpath[cache-redis]

Más ejemplos

Consulta EXAMPLES.md para más ejemplos de uso.

Comparaciones

Consulta COMPARISONS.md para comparaciones con otras herramientas de raspado web.

Avanzado: Configuración del motor y rastreador

Puedes modificar el comportamiento del motor y el rastreador de la siguiente manera:

root@kitploit:~
from wxpath import wxpath_async_blocking_iter
from wxpath.core.runtime import WXPathEngine
from wxpath.http.client.crawler import Crawler

crawler = Crawler(
    concurrency=8,
    per_host=2,
    timeout=10,
    respect_robots=False,
    headers={
        "User-Agent": "my-app/0.1.0 (contact: [email protected])", # Sites like Wikipedia will appreciate this
    },
)

# If `crawler` is not specified, a default Crawler will be created with
# the provided concurrency, per_host, and respect_robots values, or with defaults.
engine = WXPathEngine(
    # concurrency: int = 16, 
    # per_host: int = 8,
    # respect_robots: bool = True,
    # allowed_response_codes: set[int] = {200},
    # allow_redirects: bool = True,
    crawler=crawler,
)

path_expr = "url('https://en.wikipedia.org/wiki/Expression_language')//url(//main//a/@href)"

items = list(wxpath_async_blocking_iter(path_expr, max_depth=1, engine=engine))

Opciones de la API de ejecución (wxpath_async*)

  • max_depth: int = 1
  • progress: bool = False
  • engine: WXPathEngine | None = None
  • yield_errors: bool = False

Ajustes

También puedes usar settings.py para habilitar caché, limitación de velocidad, concurrencia y más.

Filosofía del proyecto

Principios

  • Permitir rastreo y raspado declarativos sin código repetitivo
  • Mantenerse ligero y componible
  • Soporte asíncrono para rastreos de alto rendimiento

Objetivos

  • Las URLs se deduplican con el mejor esfuerzo, por rastreo.
  • Los rastreos tienen como objetivo terminar una vez que la frontera se agota o se alcanza max_depth.
  • Las peticiones se realizan concurrentemente.
  • Los resultados se transmiten tan pronto como están disponibles.

Limitaciones (por ahora)

Las siguientes características aún no están soportadas:

  • Rotación automática de proxies
  • Renderizado basado en navegador (ejecución de JavaScript)
  • Orden estricto de resultados

ADVERTENCIAS!!!

Este proyecto está en desarrollo temprano. Los conceptos centrales son estables, pero la API y las características pueden cambiar. Por favor, reporta problemas – en particular, rastreos bloqueados o comportamientos inesperados – y cualquier característica que te gustaría ver (sin garantía de que se implementen).

  • Sé respetuoso al rastrear sitios web. Un limitador inspirado en Scrapy está activado por defecto.
  • Los rastreos profundos (///) requieren disciplina del usuario para evitar expansión ilimitada (explosión del recorrido).
  • Es posible que se produzcan bloqueos y cuelgues en ciertas situaciones (por ejemplo, todas las tareas esperando peticiones bloqueadas). Por favor, reporta problemas si encuentras tal comportamiento.
  • Considera usar tiempos de espera, max_depth, y predicados y filtros XPath para limitar el alcance del rastreo.

Soporte comercial / consultoría

Si deseas ayuda para construir u operar rastreadores / fuentes de datos con wxpath (extracción, planificación, monitoreo, corrección de roturas) u otras necesidades de raspado web, contáctame en: [email protected].

Donar

Si te gusta wxpath y deseas apoyar su desarrollo, considera donar.

Versionado

wxpath sigue semver: <MAJOR>.<MINOR>.<PATCH>.

Sin embargo, antes de 1.0.0 se sigue 0.<MAJOR>.<MINOR|PATCH>.

Licencia

AGPL-3.0

Descargar herramienta