🔍 Websearch — 技能工具

v0.1.1

Perform web searches using various search engines and APIs.

0· 424·1 当前·1 累计
by @roryyu·MIT-0
下载技能包
License
MIT-0
最后更新
2026/4/13
0
安全扫描
VirusTotal
无害
查看报告
OpenClaw
可疑
medium confidence
The skill's description (web searching and URL reading) is plausible, but the runtime instructions claim npm-based scripts and dependencies that are not present in the package manifest and the SKILL.md asks you to install/run code that doesn't exist here — this mismatch is suspicious and should be resolved before use.
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv0.1.12026/3/12

**Major breaking change: All core source files removed; SKILL.md now includes only documentation and sample code.** - Removed main logic files: ReadResult.js, search.js, exasearch.js, package.json, and config/mcporter.json. - SKILL.md updated to embed sample code and keep documentation only; no executable scripts included. - Usage instructions and error handling sections remain as reference. - Skill now serves as a documentation/sample reference rather than a working implementation.

无害

安装命令

点击复制
官方npx clawhub@latest install websearch-free-skill
🇨🇳 镜像加速npx clawhub@latest install websearch-free-skill --registry https://cn.longxiaskill.com

技能文档

Perform web searches using various search engines and APIs. This skill provides access to search functionality without requiring API keys for basic usage.

使用各种搜索引擎和API进行网络搜索。此技能提供搜索功能访问,无需API密钥即可进行基本操作。

Features / 功能特性

  • URL Content Extraction: Read and extract content from any web page URL
URL内容提取: 从任意网页URL读取和提取内容
  • Keyword Search: Search for specific keywords and return specified number of results
关键词搜索: 搜索特定关键词并返回指定数量的结果
  • Dependency Management: Automatic dependency installation via npm
依赖管理: 通过npm自动安装依赖项

Basic Usage / 基础用法

Read content from a specific URL:

从特定URL读取内容:

node ./search.js  [previewLength]

Parameters / 参数:

  • url: The URL to read (required)
要读取的URL(必需)
  • previewLength: Number of characters to preview (optional, default: 200, use 0 to disable preview)
预览字符数(可选,默认:200,使用0禁用预览)

Examples / 示例:

# Default preview (200 characters)
# 默认预览(200字符)
node ./search.js https://www.example.com

# Preview 500 characters # 预览500字符 node ./search.js https://www.example.com 500

# No preview (show only metadata) # 无预览(仅显示元数据) node ./search.js https://www.example.com 0

Output Format / 输出格式:

  • Title / 标题
  • URL
  • Platform / 平台
  • Content length / 内容长度
  • Content preview / 内容预览(可选)

Advanced Usage / 高级用法

Search with specific keyword and result limit:

使用特定关键词和结果限制进行搜索:

node ./exasearch.js  [numResults]

Parameters / 参数:

  • keyword: Search query string (required)
搜索查询字符串(必需)
  • numResults: Number of results to return (optional, default: 10, max: 100)
返回结果数量(可选,默认:10,最大:100)

Examples / 示例:

# Basic search with default 10 results
# 默认10个结果的基础搜索
node ./exasearch.js "artificial intelligence"

# Search with 20 results # 搜索20个结果 node ./exasearch.js "machine learning" 20

# Search with 50 results # 搜索50个结果 node ./exasearch.js "deep learning" 50

Setup / 安装设置

First-time setup requires installing dependencies:

首次使用需要安装依赖:

Prerequisites / 前置要求:

  • Node.js v22 or higher / Node.js v22 或更高版本
  • npm or yarn
npm install

Dependencies / 依赖项:

  • axios: HTTP client for web requests
HTTP客户端,用于网络请求
  • mcporter: Tool integration framework
工具集成框架

Error Handling / 错误处理

The scripts include comprehensive error handling for:

脚本包含全面的错误处理:

  • Missing required parameters / 缺少必需参数
  • Invalid parameter values / 无效参数值
  • Network connection errors / 网络连接错误
  • HTTP request failures / HTTP请求失败
  • Server timeout errors / 服务器超时错误

Technical Details / 技术细节

  • Backend / 后端: Jina Reader API (https://r.jina.ai)
  • Timeout / 超时: 15 seconds for web requests / 网络请求15秒
  • Output Format / 输出格式: JSON / Markdown
  • Search Provider / 搜索提供商: Exa API (via mcporter)

Logic Examples / 逻辑示例

ReadResult.js - Result Object Class

export class ReadResult {
  constructor(title, content, url, platform = "web") {
    this.title = title;
    this.content = content;
    this.url = url;
    this.platform = platform;
  }

toDict() { return { title: this.title, content: this.content, url: this.url, platform: this.platform }; } }

search.js - URL Content Extraction

import axios from 'axios';
import { ReadResult } from './ReadResult.js';

class WebChannel { constructor() { this.JINA_URL = "https://r.jina.ai/"; }

async read(url) { try { const response = await axios.get(${this.JINA_URL}${url}, { headers: { 'Accept': 'text/markdown' }, timeout: 15000 });

const text = response.data; let title = url; const lines = text.split('\n'); for (const line of lines) { const trimmedLine = line.trim(); if (trimmedLine.startsWith('# ')) { title = trimmedLine.substring(2).trim(); break; } if (trimmedLine.startsWith('Title:')) { title = trimmedLine.substring(6).trim(); break; } }

return new ReadResult(title, text, url, "web");

} catch (error) { if (error.response) { throw new Error(HTTP ${error.response.status}: ${error.response.statusText}); } else if (error.request) { throw new Error('Network error: No response received'); } else { throw new Error(Request failed: ${error.message}); } } } }

async function main() { const url = process.argv[2]; const previewLength = process.argv[3] ? parseInt(process.argv[3], 10) : 200; if (!url) { console.error('Usage: node search.js [previewLength]'); console.error(' url: The URL to read'); console.error(' previewLength: Number of characters to preview (optional, default: 200)'); process.exit(1); }

if (isNaN(previewLength) || previewLength < 0) { console.error('Error: previewLength must be a non-negative integer'); process.exit(1); }

const webChannel = new WebChannel(); try { console.log(Reading: ${url}); const result = await webChannel.read(url); console.log('\n=== Read Result ==='); console.log(Title: ${result.title}); console.log(URL: ${result.url}); console.log(Platform: ${result.platform}); console.log(Content length: ${result.content.length} characters); if (previewLength > 0) { console.log(\nFirst ${previewLength} characters of content:); const preview = result.content.substring(0, previewLength); console.log(preview + (result.content.length > previewLength ? '...' : '')); } } catch (error) { console.error('Error reading web page:', error.message); process.exit(1); } }

main();

exasearch.js - Keyword Search

import { callOnce } from "mcporter";

async function main() { const keyword = process.argv[2]; const num = process.argv[3];

if (!keyword) { console.error('Error: Search keyword is required'); console.error('Usage: node exasearch.js [numResults]'); process.exit(1); }

const numResults = num ? parseInt(num, 10) : 10;

if (isNaN(numResults) || numResults < 1) { console.error('Error: numResults must be a positive integer'); process.exit(1); }

if (numResults > 100) { console.error('Error: numResults cannot exceed 100'); process.exit(1); }

try { console.log(Searching for: ${keyword}); console.log(Number of results: ${numResults}); const result = await callOnce({ server: "exa", toolName: "web_search_exa", args: { query: keyword, numResults: numResults }, });

console.log('\n=== Search Results ==='); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.error('Error during search:', error.message); if (error.response) { console.error(HTTP ${error.response.status}: ${error.response.statusText}); } else if (error.request) { console.error('Network error: No response received from server'); } else if (error.code === 'ECONNREFUSED') { console.error('Connection refused: Unable to reach the search server'); } else if (error.code === 'ETIMEDOUT') { console.error('Request timeout: Server took too long to respond'); } process.exit(1); } }

main();

数据来源:ClawHub ↗ · 中文优化:龙虾技能库