Skill: dlutwuwei/web-anti-crawl-fetch (version 1.0.0)

--- name: web-fetch description: 使用带 Stealth 插件的无头浏览器抓取网页内容并转换为 Markdown。用于当需要获取特定网页的正文、新闻详情、公司财报或其他长篇网页内容时。支持绕过大多数基础反爬虫检测。 --- # Web Fetch Skill 使用无头浏览器（Playwright + Stealth Plugin）抓取指定 URL 的网页内容，并自动转换为 Markdown 格式以便于阅读和进一步处理。 ## 主要特性 - **反爬虫绕过**: 集成了 `playwright-extra` 和 `puppeteer-extra-plugin-stealth`，自动处理各种浏览器指纹和自动化特征检测。 - **内容转换**: 使用 `turndown` 库将复杂的 HTML 页面转换为简洁的 Markdown 格式。 - **环境模拟**: 模拟真实用户视口大小和无头浏览器配置。 ## 使用方法 运行抓取脚本： ```bash cd /Users/wuwei/.openclaw/workspace/skills/web-fetch/scripts node fetch.js <url> ``` ### 参数说明 - `url`: 需要抓取的完整网页 URL（包括 http/https）。 ### 示例 ```bash # 抓取新浪财经 node fetch.js "https://finance.sina.com.cn/stock/" # 抓取特定新闻页面 node fetch.js "https://finance.eastmoney.com/a/202403143012345678.html" ``` ## 输出 脚本将会在控制台输出以下内容： 1. 抓取进度说明。 2. 页面标题。 3. 转换后的 Markdown 正文内容（较长内容会截断）。 ## 依赖 - **playwright-extra**: 插件化 Playwright 核心。 - **puppeteer-extra-plugin-stealth**: 提供各种 evasion 策略。 - **turndown**: HTML 到 Markdown 转换服务。 安装依赖： ```bash cd /Users/wuwei/.openclaw/workspace/skills/web-fetch/scripts npm install ```

path: scripts/fetch.js
content: #!/usr/bin/env node

const { chromium } = require('playwright-extra');
const stealthPlugin = require('puppeteer-extra-plugin-stealth');
const TurndownService = require('turndown');

// 注册 Stealth 插件
chromium.use(stealthPlugin());

const turndownService = new TurndownService({
  headingStyle: 'atx',
  codeBlockStyle: 'fenced'
});

// 自定义规则：忽略 base64 图片
turndownService.addRule('ignore-base64-images', {
  filter: (node) => {
    return (
      node.nodeName === 'IMG' && 
      node.getAttribute('src') && 
      node.getAttribute('src').startsWith('data:image/')
    );
  },
  replacement: () => ''
});

async function fetchUrl(url) {
  console.log(`🌐 正在获取内容: ${url}`);
  console.log('---');

  let browser;
  try {
    browser = await chromium.launch({ 
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox']
    });
    
    const context = await browser.newContext({
      viewport: { width: 1920, height: 1080 }
    });
    
    const page = await context.newPage();
    page.setDefaultTimeout(60000);
    
    // 模拟真实用户行为
    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
    
    // 向下滚动三次触发懒加载内容
    console.log('📜 正在向下滚动页面以加载更多内容...');
    for (let i = 0; i < 3; i++) {
      await page.evaluate(() => window.scrollBy(0, window.innerHeight));
      await page.waitForTimeout(1000);
    }
    
    // 最后等待核心内容加载完成
    await page.waitForTimeout(2000);
    
    // 提取页面内容
    const pageData = await page.evaluate(() => {
      // 移除干扰元素
      const selectors = [
        'script', 'style', 'noscript', 'iframe', 
        'ad', '.ads', '#ads',
        'img[src^="data:image/"]' // 移除 base64 图片
      ];
      
      selectors.forEach(sel => {
        document.querySelectorAll(sel).forEach(tag => tag.remove());
      });
      
      return {
        title: document.title,
        html: document.body.innerHTML
      };
    });

    console.log(`✅ 页面标题: ${pageData.title}`);
    console.log('---');
    
    // 转换为 Markdown
    const markdown = turndownService.turndown(pageData.html);
    
    if (!markdown || markdown.trim().length === 0) {
      console.log('⚠️ 无法提取到有效正文内容');
    } else {
      // 输出前 1000 个字符
      console.log(markdown.substring(0, 20000));
      if (markdown.length > 20000) {
        console.log('\n... (内容已截断)');
      }
    }
    
  } catch (error) {
    console.error(`❌ 获取内容出错: ${error.message}`);
  } finally {
    if (browser) await browser.close();
  }
}

// 主程序
const args = process.argv.slice(2);

if (args.length < 1) {
  console.log('📖 用法: node fetch.js <url>');
  console.log('\n示例:');
  console.log('  node fetch.js "https://finance.sina.com.cn/stock/"');
  process.exit(1);
}

const targetUrl = args[0];
fetchUrl(targetUrl);


path: scripts/package.json
content: {
  "name": "web-fetch",
  "version": "1.0.0",
  "description": "Fetch web content using playwright-extra with stealth plugin and convert to markdown",
  "main": "fetch.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "playwright": "^1.58.2",
    "playwright-extra": "^3.1.2",
    "puppeteer-extra-plugin-stealth": "^2.11.2",
    "turndown": "^7.1.2"
  }
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)