关于 web-scraper
Web Scraper 是用于抓取网站并将提取文本保存到本地的命令行技能和脚本,支持递归并发采集、页面与域名限制及常见杂项过滤;仅处理静态 HTML。
主要功能
- 01递归跟踪页面链接
- 02并发发送 HTTP 请求
- 03限制页面数量与域名
- 04提取并过滤正文文本
- 05按 URL 结构保存目录
- 06记录会话元数据与错误
适用场景
- 01归档文档网站
- 02采集多个相关域名的文本
- 03按页面上限抽样大型网站
- 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"
}
}
内容提取与过滤
提取内容
抓取工具通过以下方式提取纯净的文本内容:
-
聚焦主要内容 - 优先选择
<main>、<article>或<body>标签 -
移除不需要的元素 - 清除以下内容:
- 脚本和样式
- 导航菜单
- 页眉和页脚
- 侧边栏(aside 标签)
- iframe 和嵌入内容
- SVG 图形
- 注释
-
过滤常见模式 - 移除以下内容:
- Cookie 同意消息
- 隐私政策链接
- 服务条款的模板文本
- UI 元素(箭头、单个数字)
- 很短的行(可能是导航项)
-
保留结构 - 保留内容块之间的换行
过滤掉的内容
自动移除的常见不需要的模式:
- “接受 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
实现方法
当用户请求网页抓取时:
-
确定范围:
- 从哪些 URL 开始?
- 是否应跟踪链接?跟踪深度是多少?
- 是否需要域名限制?
- 页面数量限制是否合理?
-
配置抓取工具:
- 设置适当的深度(通常为 1-3)
- 设置 max-pages,避免抓取失控
- 根据站点规模选择并发级别
- 确定域名限制
-
运行并监控:
- 从详细模式或少量样本开始
- 监控输出,检查错误或意外内容
- 根据需要调整配置
-
验证输出:
- 检查输出目录结构
- 查看
_metadata.json中的统计信息 - 抽查几个文本文件,确认质量
- 检查元数据中的错误
-
处理内容:
- 文本文件可直接加载到上下文中
- 使用 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
最佳实践
- 从小规模开始 - 大规模抓取前,先使用
--depth 1 --max-pages 10测试 - 尊重服务器 - 设置合理的并发数和超时时间
- 设置限制 - 首次运行时务必使用
--max-pages - 检查 robots.txt - 手动确认站点允许抓取
- 使用详细模式 - 监控错误和意外行为
- 表明身份 - 使用包含联系信息的描述性 User-Agent
- 监控输出 - 检查
_metadata.json中的错误和统计信息 - 妥善处理错误 - 查看元数据中的错误日志,找出有问题的 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,但不会在多次运行之间持久保存。为避免重复下载:
- 限制抓取范围,执行初始抓取
- 检查输出目录,确认已下载的内容
- 使用不同的起始 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 提供全面的命令行帮助。