CommunityRedacción y edicióngithub.com

Búsqueda Local

Habilidad de búsqueda web que se ejecuta completamente en la máquina del usuario — sin dependencia de Z.AI / SDK en la nube. Scraping HTML de DuckDuckGo / Bing / Google con retroceso automático entre motores.

¿Qué es Búsqueda Local?

Local Search es una habilidad de agente de IA que permite realizar búsquedas en la web pública directamente desde la máquina del usuario, sin necesidad de API keys, SDKs en la nube ni infraestructura externa. Utiliza scraping HTML directo de DuckDuckGo, Bing y Google, con un orquestador inteligente que retrocede automáticamente al siguiente motor si el actual impone límites de tasa, garantizando así una alta tasa de éxito incluso desde IPs de datacenter donde Google suele estar bloqueado. Es compatible con Node 18+ y Bun, y se usa tanto desde línea de comandos como desde código TypeScript/JavaScript, proporcionando un esquema de resultados canónico con 7 campos estándar y 3 campos opcionales de extensión. Es ideal para obtener información en tiempo real, documentación actualizada, verificación de hechos y análisis de competencia, todo sin salir del entorno local del desarrollador.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add Sakurakilove/local-search

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Vista previa

Del README del skill

ClawHub
Versión
Licencia: MIT
Node

Documentación

Habilidad de Búsqueda Local

Búsqueda web local con retroceso automático entre motores. Scraping HTML directo de DuckDuckGo / Bing / Google · resistente a límites de tasa · esquema de resultados canónico.

ClawHub Versión Licencia: MIT Node

Esta habilidad llama a los motores de búsqueda públicos directamente desde tu máquina. Sin clave API, sin SDK, sin saltos de red. Si un motor te está limitando la tasa, el orquestador retrocede silenciosamente al siguiente — por lo que la llamada suele tener éxito en el primer intento, incluso desde IPs de datacenter donde Google está bloqueado.

Cada resultado es un SearchFunctionResultItem con los 7 campos canónicos (url, name, snippet, host_name, rank, date, favicon) más tres campos de extensión opcionales: source_engine, raw_html, score. El código consumidor escrito para cualquier habilidad de búsqueda web con forma similar funciona aquí sin cambios.

✨ Destacados

  • Dependencia cero de SDK en la nube — solo cheerio (analizador HTML) y el fetch integrado de Node.
  • Tres motores, retroceso automático — DuckDuckGo → Bing → Google cuando engine: "auto" (por defecto).
  • Consciente de configuración regional — --locale en-US / zh-CN / ja-JP / cualquier etiqueta BCP-47. Crítico para IPs no estadounidenses donde Bing muestra resultados localizados incluso para consultas en inglés.
  • Filtro de actualidad — --recency-days 7 restringe a resultados de la última semana. DDG admite días exactos; Bing/Google usan bloques de día/semana/mes.
  • Esquema de resultados canónico — campos url / name / snippet / host_name / rank / date / favicon, idénticos en forma a otras habilidades de búsqueda web en el registro de ClawHub.
  • CLI + SDK — usa tsx bin/web-search.ts <consulta> para usos puntuales, o import { search } from "local-search" en código.
  • TypeScript ESM puro — se ejecuta en Node 18+ con tsx, o sin configuración con bun.

🚀 Inicio Rápido

# 1. Instalar (una dependencia de ejecución: cheerio)
cd skills/local-search && npm install

# 2. Buscar (retroceso automático entre DDG → Bing → Google)
tsx bin/web-search.ts "inteligencia artificial"

# 3. Fijar un motor y configuración regional específicos
tsx bin/web-search.ts "aprendizaje automático" --engine bing --locale en-US --num 5

# 4. Noticias recientes como JSON
tsx bin/web-search.ts "avances en IA" --recency-days 7 --json -o ai_news.json

Uso programático:

import { search } from "local-search";

const outcome = await search("¿Cuál es la capital de Francia?", { num: 5 });
if (outcome.success) {
  console.log(`Respondido por ${outcome.engine} en ${outcome.elapsedMs}ms`);
  outcome.results.forEach(r => console.log(`- ${r.name}\n  ${r.url}`));
}

🎯 Cuándo Usar Esta Habilidad

Usa local-search cuando el usuario necesite información que vive en la web pública — más allá de lo que está en los datos de entrenamiento del modelo:

  • Información en tiempo real: noticias actuales, precios de acciones, clima, resultados deportivos
  • Documentación más reciente: notas de versión de frameworks, cambios en APIs, artículos recién publicados
  • Verificación de hechos: comprobar una afirmación contra fuentes web en vivo
  • Investigación: recopilar múltiples fuentes sobre un tema, comparar perspectivas
  • Descubrimiento de contenido: encontrar tutoriales, publicaciones de blog, charlas recientes
  • Análisis competitivo / de mercado: anuncios de competidores, tendencias de la industria
  • Consulta académica: buscar artículos, citas, páginas de autores

🔄 Comparación de Motores

MotorEndpointClave APIIP ResidencialIP de DatacenterActualidad
DuckDuckGohtml.duckduckgo.com/html/ (GET)ninguna✅ alta⚠️ límites de tasa bajo cargadf=d<N> (días exactos)
Bingwww.bing.com/searchninguna✅ alta✅ altafreshness=d1|w1|m1 (en bloques)
Googlewww.google.com/searchninguna⚠️ media❌ baja (pantalla enablejs)tbs=qdr:d|w|m|y (en bloques)

engine: "auto" los prueba en orden DuckDuckGo → Bing → Google, devolviendo el primer conjunto de resultados no vacío. Desde una IP de datacenter la cadena efectiva es DDG → Bing (Google suele estar bloqueado); desde una IP residencial los tres son viables. Edita AUTO_ENGINE_ORDER en src/engines/index.ts para cambiar la prioridad.

📦 Ruta de Instalación

Ubicación recomendada: {project_path}/skills/local-search

Extrae este paquete de habilidad a la ruta anterior en tu proyecto.

Prerrequisitos

  • Node.js >= 18 (usa el fetch global integrado).
  • Una dependencia npm: cheerio (analizador HTML).
  • Una conexión a Internet funcional — la habilidad llama a los motores de búsqueda públicos directamente.

Instala una vez en el directorio de la habilidad:

cd {project_path}/skills/local-search
npm install            # o: bun install / pnpm install

La habilidad es TypeScript ESM puro. Puedes ejecutarla con tsx (recomendado, amigable para desarrollo) o bun (sin configuración). También funciona node --experimental-strip-types bin/web-search.ts en Node 22+.

¿Por Qué Local?

AspectoHabilidades de búsqueda en la nubeEsta habilidad (local-search)
Backend de búsquedaFunción en la nube / APIHTTP directo a DuckDuckGo / Bing / Google
Clave API / SDKRequeridoNinguno
Ruta de redCliente → nube → motor de búsquedaCliente → motor de búsqueda
Manejo de fallosDependiente del SDKRetroceso automático entre 3 motores
Esquema de resultadosSearchFunctionResultItem (7 campos)Mismos 7 campos + 3 campos opcionales de extensión
CLIEspecífico del SDKtsx bin/web-search.ts

Arquitectura

local-search/
├── SKILL.md                 ← estás aquí
├── LICENSE.txt
├── package.json             ← declara la dependencia `cheerio`
├── tsconfig.json
├── bin/
│   └── web-search.ts        ← entrada CLI
├── src/
│   ├── index.ts             ← exportaciones públicas del SDK
│   ├── search.ts            ← orquestador con retroceso automático
│   ├── types.ts             ← SearchFunctionResultItem + opciones
│   └── engines/
│       ├── _shared.ts       ← ayudantes de fetch / análisis
│       ├── duckduckgo.ts    ← POST https://html.duckduckgo.com/html/
│       ├── bing.ts          ← GET https://www.bing.com/search
│       ├── google.ts        ← GET https://www.google.com/search
│       └── index.ts         ← registro de motores + AUTO_ENGINE_ORDER
└── scripts/
    └── web_search.ts        ← ejemplo de inicio rápido

La única dependencia de ejecución es cheerio (analizador HTML), declarada en package.json. El fetch integrado de Node 18+ cubre la capa de red — no se importa ningún otro SDK en este paquete.

Uso de la CLI

La CLI reside en bin/web-search.ts. Ejecútala con tsx, bun o cualquier ejecutor compatible con TS.

Búsqueda Básica

# Por defecto: motor automático, 10 resultados, salida legible para humanos
tsx bin/web-search.ts "inteligencia artificial"

# Limitar número de resultados
tsx bin/web-search.ts "aprendizaje automático" --num 5
# (la opción corta también funciona)
tsx bin/web-search.ts "aprendizaje automático" -n 5

Fijar un Motor Específico

# Forzar solo DuckDuckGo
tsx bin/web-search.ts "últimas noticias de tecnología" --engine duckduckgo
# Forzar solo Bing
tsx bin/web-search.ts "últimas noticias de tecnología" --engine bing
# Forzar solo Google (mayor calidad, más propenso a límites de tasa)
tsx bin/web-search.ts "últimas noticias de tecnología" --engine google
# Por defecto — probar DDG → Bing → Google, devolver el primer no vacío
tsx bin/web-search.ts "últimas noticias de tecnología" --engine auto

Filtro de Actualidad

# Resultados de los últimos 7 días
tsx bin/web-search.ts "noticias de criptomonedas" --num 10 --recency-days 7
# (opción corta)
tsx bin/web-search.ts "noticias de criptomonedas" -r 7

Guardar Resultados en JSON

# Escribir JSON a un archivo (el banner legible se suprime)
tsx bin/web-search.ts "investigación sobre cambio climático" --num 5 --json -o search_results.json

# O canalizar JSON a la salida estándar
tsx bin/web-search.ts "avances en IA" --num 3 --recency-days 1 --json > ai_news.json

Modo Silencioso (Scripts / Tuberías)

# Suprimir el banner de "motor / temporización" — solo imprimir los resultados
tsx bin/web-search.ts "react hooks" --quiet

Parámetros de la CLI

FlagCortoDescripción
--num <N>-nNúmero de resultados (por defecto: 10, máximo: 50)
--engine <id>-educkduckgo | bing | google | auto (por defecto: auto)
--recency-days <N>-rRestringir a resultados de los últimos N días (por defecto: 0 = sin filtro)
--timeout <ms>—Tiempo de espera por motor en ms (por defecto: 8000)
--json—Emitir JSON en lugar de salida legible
--output <ruta>-oEscribir JSON a un archivo en lugar de la salida estándar
--pretty—Imprimir JSON de forma bonita (por defecto activado; pasa --no-pretty para desactivar — aún no soportado, omite --json en su lugar)
--quiet-qSuprimir el banner de información del motor
--help-hMostrar ayuda

Estructura del Resultado de Búsqueda

Cada elemento de resultado es un SearchFunctionResultItem:

interface SearchFunctionResultItem {
  // ----- Campos canónicos (forma compartida entre habilidades de búsqueda web de ClawHub) -----
  url: string;          // URL completa del resultado
  name: string;         // Título de la página
  snippet: string;      // Texto de vista previa / descripción
  host_name: string;    // Nombre de dominio (ej. "en.wikipedia.org")
  rank: number;         // Clasificación basada en 1 dentro del conjunto de resultados del motor
  date: string;         // Fecha de publicación / actualización; "N/A" cuando se desconoce
  favicon: string;      // URL del favicon (Google S2)

  // ----- Campos de extensión (nuevos en local-search) -----
  source_engine: "duckduckgo" | "bing" | "google";
  raw_html?: string;    // HTML original del elemento de snippet (opcional)
  score?: number;       // Puntuación de relevancia heurística [0, 100] (opcional)
}

Uso del SDK

Si estás escribiendo código TypeScript/JavaScript (no ejecutando la CLI), importa desde src/index.ts:

Búsqueda Simple

import { search } from "local-search";

const outcome = await search("¿Cuál es la capital de Francia?", { num: 5 });

if (outcome.success) {
  console.log(`Motor usado: ${outcome.engine}`);
  console.log(`Probados en orden: ${outcome.enginesTried.join(" → ")}`);
  console.log(`Transcurrido: ${outcome.elapsedMs}ms`);
  for (const item of outcome.results) {
    console.log(`- ${item.name}  [${item.source_engine}]`);
    console.log(`  ${item.url}`);
    console.log(`  ${item.snippet}`);
  }
} else {
  console.error("Búsqueda fallida:", outcome.error);
  if (outcome.errors) {
    // Modo automático: ver qué motores se probaron y qué informaron
    for (const e of outcome.errors) {
      console.error(`  ${e.engine}:`, e.error);
    }
  }
}

Variante con Lanzamiento de Excepción en Fallo

import { searchOrThrow, AllEnginesFailedError } from "local-search";

try {
  const results = await searchOrThrow("Frameworks de JavaScript", { num: 10 });
  console.log(results);
} catch (err) {
  if (err instanceof AllEnginesFailedError) {
    console.error("Todos los motores fallaron:", err.errors);
  } else {
    console.error("Error de un solo motor:", err);
  }
}

Fijar un Motor Específico

import { search } from "local-search";

// Saltar la cadena de retroceso — usar solo DuckDuckGo.
const outcome = await search("aplicaciones de computación cuántica", {
  num: 8,
  engine: "duckduckgo",
});

Filtro de Actualidad

const outcome = await search("investigación en genómica", {
  num: 5,
  recency_days: 30, // últimos 30 días
});

Fetch Personalizado (Pruebas / Entornos de Ejecución Edge)

const outcome = await search("hola mundo", {
  fetchImpl: myMockFetch, // cualquier función compatible con WhatWG-fetch
  userAgent: "mi-bot/1.0",
  timeoutMs: 5000,
});

Motores Backend

DuckDuckGo (duckduckgo)

  • Endpoint: https://html.duckduckgo.com/html/ (formulario POST q=...)
  • Sin clave API. Sujeto a límites de tasa aproximados — el uso intensivo sostenido devuelve conjuntos de resultados vacíos.
  • Actualidad: campo de formulario df=d<N>.
  • Mejor para: primer intento por defecto; raramente bloqueado directamente; respeta la privacidad.

Bing (bing)

  • Endpoint: https://www.bing.com/search?q=...&count=...
  • Sin clave API. El diseño HTML es estable y fácil de analizar.
  • Actualidad: bloque freshness=d1 / w1 / m1 (Bing no tiene un filtro de URL de N días arbitrarios).
  • Mejor para: segundo retroceso; buenos resultados en inglés; peculiaridades ocasionales de configuración regional (mitigadas por ensearch=1).

Google (google)

  • Endpoint: https://www.google.com/search?q=...&num=...
  • Sin clave API, PERO Google es el más agresivo bloqueando scrapers. Desde IPs de datacenter / nube Google generalmente devuelve una página de redirección "por favor, habilite JS" (/httpservice/retry/enablejs) con cero resultados analizables — el motor muestra esto como un fallo suave y la cadena automática retrocede. Desde IPs residenciales, el scraping HTML de Google a menudo funciona bien.
  • Actualidad: bloque tbs=qdr:d|w|m|y.
  • Mejor para: retroceso de último recurso en IPs residenciales; generalmente fallará en IPs de nube (donde DDG+Bing ya cubren la necesidad).

Estrategia de Retroceso Automático

Cuando engine: "auto" (el valor por defecto), el orquestador prueba los motores en este orden:

  1. DuckDuckGo — bloqueo menos agresivo, filtro de fecha más detallado
  2. Bing — generalmente estable desde cualquier IP, incluyendo datacenter
  3. Google — mejor calidad de resultado cuando es accesible; a menudo bloqueado en IPs de datacenter

Devuelve el primer motor que produce ≥ 1 resultado. Si los tres fallan, el resultado es { success: false, errors: [...] } con el error de cada motor adjunto — o, en modo searchOrThrow, un AllEnginesFailedError.

Tabla de fiabilidad práctica (observada durante las pruebas):

Tipo de IP del llamanteDDGBingGoogleCadena automática efectiva
ResidencialaltaaltamediaDDG → Bing → Google (3 viables)
Datacenter / nubemedia (límites de tasa bajo carga)altabaja (pantalla enablejs)efectivamente DDG → Bing

El orden se define en src/engines/index.ts (AUTO_ENGINE_ORDER); edita ese array si deseas una prioridad diferente.

Casos de Uso Comunes

  1. Información en tiempo real — noticias de última hora, clima, resultados deportivos, precios de acciones
  2. Documentación más reciente — notas de versión de frameworks, cambios en APIs, documentación actualizada
  3. Verificación de hechos — comprobar afirmaciones contra fuentes web en vivo para precisión
  4. Investigación — recopilar múltiples perspectivas sobre un tema para un análisis completo
  5. Descubrimiento de contenido — encontrar tutoriales, ejemplos de código, mejores prácticas
  6. Análisis competitivo — rastrear anuncios de competidores, tendencias del mercado
  7. Consulta académica — buscar artículos de investigación, citas académicas, páginas de autores
  8. Depuración — encontrar problemas conocidos, correcciones de errores, discusiones de la comunidad

Solución de Problemas

SíntomaCausa probableSolución
DuckDuckGo devuelve un conjunto vacíoLímite de tasa alcanzadoEspera unos segundos o usa --engine bing
Google devuelve "Habilite JavaScript"IP de datacenter / nubeUsa --engine auto (retrocede a Bing) o --engine duckduckgo
Resultados de Bing en un idioma inesperadoConfiguración regional de la IPSiempre usa --locale en-US (o tu BCP-47)
La búsqueda funciona en la CLI pero no en el códigoRuta de importación incorrectaImporta desde local-search o la ruta relativa a src/index.ts
La búsqueda falla con un error de redSin conectividad / proxy bloqueanteVerifica la conexión a Internet / complementos de firewall
El resultado date es "N/A" para todos los motoresEl motor no expuso fechasEs normal para algunos hitos — el campo siempre se proporciona

Limitaciones

  • No adecuado para búsqueda a gran escala — el uso intensivo sostenido desencadenará límites de tasa en DuckDuckGo y posiblemente en Bing. Estas herramientas están diseñadas para consultas esporádicas y bajo demanda disparadas por un usuario humano.
  • Sin acceso a APIs de búsqueda premium — no se puede acceder a Google Custom Search, Bing Web Search API ni ningún servicio de nivel pago. Los resultados son puramente de scraping HTML público.
  • Dependencia de la estabilidad del diseño HTML — si DuckDuckGo, Bing o Google rediseñan sus páginas de resultados, esta habilidad puede necesitar una actualización para adaptarse al nuevo diseño. El autor monitorea y actualiza activamente.
  • JSON de salida sin streaming — la CLI recopila todos los resultados y luego los emite; no hay resultados en streaming mientras llegan. Esto es intencional: el orquestador espera hasta que un motor termina (o falla) antes de decidir retroceder.

Preguntas Frecuentes

P: ¿Se ejecuta esto en una función en la nube?
R: No. La habilidad ejecuta el scraping HTML directamente desde tu máquina. Sin intermediarios.

P: ¿Necesito una clave API?
R: No para DuckDuckGo, Bing ni Google. Todo es scraping de HTML público.

P: ¿Funciona esto en un entorno de nube (AWS Lambda, etc.)?
R: Sí, pero ten en cuenta: desde IPs de nube, Google es generalmente inaccesible. El motor automático retrocede a Bing, que funciona bien desde direcciones IP de nube.

P: ¿Cómo maneja la habilidad las diferencias de configuración regional?
R: Pasa --locale en-US (o zh-CN, ja-JP, cualquier BCP-47). Esto es particularmente importante para Bing, que por defecto sirve versiones localizadas según la IP.

P: ¿Puedo cambiar el orden de retroceso?
R: Sí. Edita AUTO_ENGINE_ORDER en src/engines/index.ts. Reordena el array como desees.

P: ¿Cuántos resultados puedo obtener?
R: El máximo es 50 (el límite de Google). El valor por defecto es 10. Valores más altos significan más solicitudes a medida que el motor de búsqueda carga más páginas.

P: ¿Puedo usar esto con Bun?
R: Sí. bun bin/web-search.ts "consulta" funciona inmediatamente (sin npm install necesario).


Hecho con ❤️ para desarrolladores que quieren búsqueda web directa y sin complicaciones.

Skills relacionados