mcpField
W
web-scraper

web-scraper

github.com/igosuki数据与数据库157 次安装53 周前更新
代码仓库

关于 web-scraper

Web Scraper 是用于抓取网站并将提取文本保存到本地的命令行技能和脚本,支持递归并发采集、页面与域名限制及常见杂项过滤;仅处理静态 HTML。

主要功能

  1. 01递归跟踪页面链接
  2. 02并发发送 HTTP 请求
  3. 03限制页面数量与域名
  4. 04提取并过滤正文文本
  5. 05按 URL 结构保存目录
  6. 06记录会话元数据与错误

适用场景

  1. 01归档文档网站
  2. 02采集多个相关域名的文本
  3. 03按页面上限抽样大型网站
  4. 04为研究建立本地文本集

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/igosuki/claude-skills --skill web-scraper

安装后在 Claude Code 中输入/web-scraper确认已加载。

附带文件scripts/scrape.py

详细介绍

网页爬虫

概述

递归抓取网页,并通过并发处理提取干净的文本内容,同时跟踪链接。爬虫会自动处理 URL 去重,根据 URL 结构创建合适的目录层级,过滤不需要的内容,并遵守域名范围限制。

何时使用此技能

当用户请求以下操作时,请使用此技能:

  • 抓取网站内容
  • 从在线来源下载文档
  • 大规模提取网页文本
  • 爬取网站以收集信息
  • 在本地归档网页内容
  • 跟踪并下载链接页面
  • 从网络来源收集研究数据
  • 根据网站构建文本数据集

前提条件

安装所需依赖:

pip install aiohttp beautifulsoup4 lxml aiofiles

这些库提供以下功能:

  • aiohttp - 用于并发请求的异步 HTTP 客户端
  • beautifulsoup4 - HTML 解析和内容提取
  • lxml - 快速 HTML/XML 解析器
  • aiofiles - 异步文件 I/O

核心功能

1. 抓取单个页面

抓取单个页面,不跟踪链接:

python scripts/scrape.py <URL> <output-directory> --depth 0

示例:

python scripts/scrape.py https://example.com/article output/

此操作只会下载指定页面,提取干净的文本内容,并将其保存到 output/example.com/article.txt。

2. 递归抓取并跟踪链接

抓取页面,并按指定深度跟踪链接:

python scripts/scrape.py <URL> <output-directory> --depth <N>

示例:

python scripts/scrape.py https://docs.example.com output/ --depth 2

深度级别:

  • --depth 0 - 仅抓取起始 URL
  • --depth 1 - 起始 URL + 这些页面上的所有链接
  • --depth 2 - 起始 URL + 链接 + 这些链接页面上的链接
  • --depth 3+ - 按指定深度继续跟踪链接
3. 限制页面数量

设置页面数量上限,避免过度抓取:

python scripts/scrape.py <URL> <output-directory> --depth 3 --max-pages 100

示例:

python scripts/scrape.py https://docs.example.com output/ --depth 3 --max-pages 50

适用于:

  • 在完整运行前测试爬虫配置
  • 限制资源使用量
  • 从大型网站抽取样本内容
  • 遵守速率限制
4. 并发处理

控制同时发出的请求数量,以加快抓取速度:

python scripts/scrape.py <URL> <output-directory> --concurrent <N>

示例:

python scripts/scrape.py https://docs.example.com output/ --depth 2 --concurrent 20

默认并发请求数为 10。增加数量可加快抓取速度,减少数量则可更谨慎地使用资源。

指南:

  • 小型网站或速度较慢的服务:--concurrent 5
  • 中型网站:--concurrent 10(默认值)
  • 大型、速度较快的网站:--concurrent 20-30
  • 请合理使用服务器资源
5. 域名限制

默认情况下,爬虫只跟踪与起始 URL 属于同一域名的链接。可按需调整:

仅限同一域名(默认):

python scripts/scrape.py https://example.com output/ --depth 2

跟踪外部链接:

python scripts/scrape.py https://example.com output/ --depth 2 --follow-external

指定允许的域名:

python scripts/scrape.py https://example.com output/ --depth 2 --allowed-domains example.com docs.example.com blog.example.com

在以下情况下使用 --allowed-domains:

  • 文档分布在多个子域名上
  • 内容横跨相关域名
  • 你希望限定为特定的可信域名
6. 多个起始 URL

同时从多个起始位置开始抓取:

python scripts/scrape.py <URL1> <URL2> <URL3> <output-directory>

示例:

python scripts/scrape.py https://example.com/docs https://example.com/guides https://example.com/tutorials output/ --depth 2

所有起始 URL 都使用相同的配置(深度、域名限制等)进行处理。

7. 请求配置

自定义 HTTP 请求行为:

python scripts/scrape.py <URL> <output-directory> --user-agent "MyBot/1.0" --timeout 60

选项:

  • --user-agent - 自定义 User-Agent 标头(默认值:"Mozilla/5.0 (compatible; WebScraper/1.0)")
  • --timeout - 请求超时时间,单位为秒(默认值:30)

示例:

python scripts/scrape.py https://example.com output/ --depth 2 --user-agent "MyResearchBot/1.0 (+https://mysite.com/bot)" --timeout 45
8. 详细输出

启用详细日志,监控抓取进度:

python scripts/scrape.py <URL> <output-directory> --verbose

详细模式会显示:

  • 正在抓取的每个 URL
  • 成功保存的文件及其路径
  • 错误和超时信息
  • 详细错误信息

输出结构

目录层级

爬虫会创建与 URL 结构对应的目录层级:

output/
├── example.com/
│   ├── index.txt              # https://example.com/
│   ├── about.txt              # https://example.com/about
│   ├── docs/
│   │   ├── index.txt          # https://example.com/docs/
│   │   ├── getting-started.txt
│   │   └── api/
│   │       └── reference.txt
│   └── blog/
│       ├── post-1.txt
│       └── post-2.txt
├── docs.example.com/
│   └── guide.txt
└── _metadata.json
文件格式

每个抓取的页面都会保存为文本文件,格式如下:

URL: https://example.com/docs/guide
Title: Getting Started Guide
Scraped: 2025-10-21T14:30:00

================================================================================

[Clean extracted text content]
元数据文件

_metadata.json 包含抓取会话信息:

{
  "start_time": "2025-10-21T14:30:00",
  "end_time": "2025-10-21T14:35:30",
  "pages_scraped": 42,
  "total_visited": 45,
  "errors": {
    "https://example.com/broken": "HTTP 404",
    "https://example.com/slow": "Timeout"
  }
}

内容提取与过滤

提取内容

抓取工具通过以下方式提取纯净的文本内容:

  1. 聚焦主要内容 - 优先选择 <main>、<article> 或 <body> 标签

  2. 移除不需要的元素 - 清除以下内容:

    • 脚本和样式
    • 导航菜单
    • 页眉和页脚
    • 侧边栏(aside 标签)
    • iframe 和嵌入内容
    • SVG 图形
    • 注释
  3. 过滤常见模式 - 移除以下内容:

    • Cookie 同意消息
    • 隐私政策链接
    • 服务条款的模板文本
    • UI 元素(箭头、单个数字)
    • 很短的行(可能是导航项)
  4. 保留结构 - 保留内容块之间的换行

过滤掉的内容

自动移除的常见不需要的模式:

  • “接受 Cookie”/“全部拒绝”
  • “Cookie 设置”
  • “隐私政策”
  • “服务条款”
  • 导航箭头(←、→、↑、↓)
  • 单独的数字
  • 少于 3 个字符的行

常见用法模式

下载文档站点

在合理限制下抓取整个文档站点:

python scripts/scrape.py https://docs.example.com docs-archive/ --depth 3 --max-pages 200 --concurrent 15
归档博客

从博客下载所有博文(遵循分页):

python scripts/scrape.py https://blog.example.com blog-archive/ --depth 2 --max-pages 500
收集研究数据

从多个相关来源收集文本内容:

python scripts/scrape.py https://research.edu/papers https://research.edu/publications research-data/ --depth 2 --allowed-domains research.edu --concurrent 20
抽样抓取大型站点

在全面抓取前,先用少量样本测试配置:

python scripts/scrape.py https://largeSite.com sample/ --depth 2 --max-pages 20 --verbose

确认结果后,再运行全面抓取:

python scripts/scrape.py https://largeSite.com full-archive/ --depth 3 --max-pages 500 --concurrent 15
多域名知识库

跨多个已授权域名进行抓取:

python scripts/scrape.py https://main.example.com knowledge-base/ --depth 3 --allowed-domains main.example.com docs.example.com wiki.example.com --max-pages 300

实现方法

当用户请求网页抓取时:

  1. 确定范围:

    • 从哪些 URL 开始?
    • 是否应跟踪链接?跟踪深度是多少?
    • 是否需要域名限制?
    • 页面数量限制是否合理?
  2. 配置抓取工具:

    • 设置适当的深度(通常为 1-3)
    • 设置 max-pages,避免抓取失控
    • 根据站点规模选择并发级别
    • 确定域名限制
  3. 运行并监控:

    • 从详细模式或少量样本开始
    • 监控输出,检查错误或意外内容
    • 根据需要调整配置
  4. 验证输出:

    • 检查输出目录结构
    • 查看 _metadata.json 中的统计信息
    • 抽查几个文本文件,确认质量
    • 检查元数据中的错误
  5. 处理内容:

    • 文本文件可直接加载到上下文中
    • 使用 Read 工具查看特定文件
    • 使用 Grep 搜索所有已抓取的内容
    • 根据分析需要加载文件

快速参考

命令结构:

python scripts/scrape.py <URL> [URL2 ...] <output-dir> [options]

必要选项:

  • -d, --depth N - 最大链接深度(默认值:2)
  • -m, --max-pages N - 最大抓取页面数
  • -c, --concurrent N - 并发请求数(默认值:10)
  • -f, --follow-external - 跟踪外部链接
  • -a, --allowed-domains - 指定允许的域名
  • -v, --verbose - 输出详细信息
  • -u, --user-agent - 自定义 User-Agent
  • -t, --timeout - 请求超时时间(秒)

查看完整帮助:

python scripts/scrape.py --help

最佳实践

  1. 从小规模开始 - 大规模抓取前,先使用 --depth 1 --max-pages 10 测试
  2. 尊重服务器 - 设置合理的并发数和超时时间
  3. 设置限制 - 首次运行时务必使用 --max-pages
  4. 检查 robots.txt - 手动确认站点允许抓取
  5. 使用详细模式 - 监控错误和意外行为
  6. 表明身份 - 使用包含联系信息的描述性 User-Agent
  7. 监控输出 - 检查 _metadata.json 中的错误和统计信息
  8. 妥善处理错误 - 查看元数据中的错误日志,找出有问题的 URL

故障排除

常见问题:

  • “缺少必需的依赖项”:运行 pip install aiohttp beautifulsoup4 lxml aiofiles
  • 超时次数过多:增大 --timeout 或减小 --concurrent
  • 抓取速度太慢:增大 --concurrent(例如,设为 20-30)
  • 大规模抓取时出现内存问题:减小 --concurrent,或使用 --max-pages 分批处理
  • 跟踪的链接过多:减小 --depth,或启用仅限同一域名(默认)
  • 缺少内容:某些网站可能需要 JavaScript;此抓取工具仅处理静态 HTML
  • HTTP 错误:查看 _metadata.json 的 errors 部分,了解具体问题

限制:

  • 不执行 JavaScript(单页应用可能无法正常运行)
  • 不处理身份验证或登录
  • 不跟踪 JavaScript 中或动态加载内容里的链接
  • 没有内置的速率限制(使用 --concurrent 控制请求速率)

高级用例

加载抓取的内容

抓取完成后,使用 Read 工具将内容加载到上下文中:

# Read a specific scraped page
Read file_path: output/docs.example.com/guide.txt

# Search across all scraped content
Grep pattern: "API endpoint" path: output/ -r
选择性重新抓取

抓取工具会在会话期间于内存中跟踪已访问的 URL,但不会在多次运行之间持久保存。为避免重复下载:

  1. 限制抓取范围,执行初始抓取
  2. 检查输出目录,确认已下载的内容
  3. 使用不同的起始 URL 或配置执行其他抓取
与其他工具组合使用

将抓取工具与其他处理工具串联:

# Scrape then process with custom script
python scripts/scrape.py https://example.com output/ --depth 2
python your_analysis_script.py output/

资源

scripts/scrape.py

主要的网页抓取工具,实现并发爬取、内容提取和智能过滤。主要功能:

  • 异步/并发处理——使用 asyncio 和 aiohttp 执行高性能并发请求
  • URL 规范化——移除片段和尾部斜杠,以便正确去重
  • 访问记录——维护 visited_urls 和 queued_urls 集合,防止重复下载
  • 智能内容提取——移除脚本、样式、导航内容和常见的不需要内容
  • 目录层级——将 URL 转换为安全的文件系统路径,同时保留目录结构
  • 错误处理——在元数据文件中跟踪并报告错误
  • 元数据生成——创建 _metadata.json,其中包含抓取统计信息和错误

该脚本可直接执行,并通过 --help 提供全面的命令行帮助。

评论

支持 Markdown