315 lines
12 KiB
Markdown
315 lines
12 KiB
Markdown
---
|
||
name: web-scraping-toolkit
|
||
description: "五个网页抓取工具的使用手册 — Jina Reader(快)、Crawl4AI(深)、Scrapling(反爬)、CamouFox(隐身浏览器)、AutoCLI(Chrome登录态复用+AI生成)"
|
||
version: 1.1
|
||
tools:
|
||
- jina-reader
|
||
- crawl4ai
|
||
- scrapling
|
||
- camoufox
|
||
- autocli
|
||
---
|
||
|
||
# Web Scraping Toolkit
|
||
|
||
四个工具互补,覆盖从单页到批量、从简单到反爬的全场景。
|
||
|
||
## 1. Jina Reader — 单页极速抓取
|
||
|
||
**适用场景:** 快速抓取单个 URL 的正文内容,返回 Markdown 格式。最适合调研、阅读文章、提取信息。
|
||
|
||
**无需 API Key**,直接用 HTTP 请求:
|
||
|
||
```python
|
||
# 终端/curl 方式(最快)
|
||
# curl -s -L "https://r.jina.ai/{URL}" -H "Accept: text/plain"
|
||
|
||
# Python 方式
|
||
import requests
|
||
|
||
def jina_read(url: str) -> str:
|
||
"""抓取单个页面,返回 Markdown 文本"""
|
||
resp = requests.get(
|
||
f"https://r.jina.ai/{url}",
|
||
headers={"Accept": "text/plain"}
|
||
)
|
||
return resp.text
|
||
|
||
# 高级用法 — 返回 JSON(含标题、链接等元数据)
|
||
def jina_read_json(url: str) -> dict:
|
||
resp = requests.get(
|
||
f"https://r.jina.ai/{url}",
|
||
headers={"Accept": "application/json"}
|
||
)
|
||
return resp.json()
|
||
```
|
||
|
||
**高级 Header:**
|
||
- `X-With-Links-Summary: true` — 返回页面所有链接
|
||
- `X-With-Images-Summary: true` — 返回页面所有图片
|
||
- `X-Return-Format: html` — 返回原始 HTML 而非 Markdown
|
||
- `X-Set-Cookie: key=value` — 传递 Cookie
|
||
|
||
**限制:** 免费额度有速率限制(约 20 req/min),大批量请用 Crawl4AI。
|
||
|
||
---
|
||
|
||
## 2. Crawl4AI — 批量深度抓取
|
||
|
||
**适用场景:** 批量抓取整个网站、多页爬取、JS 渲染页面、结构化数据提取。
|
||
|
||
```python
|
||
import asyncio
|
||
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
|
||
|
||
async def crawl_single(url: str):
|
||
"""抓取单页(带 JS 渲染)"""
|
||
browser_config = BrowserConfig(headless=True)
|
||
run_config = CrawlerRunConfig(cache_mode=CacheMode.BYPASS)
|
||
|
||
async with AsyncWebCrawler(config=browser_config) as crawler:
|
||
result = await crawler.arun(url=url, config=run_config)
|
||
return {
|
||
"url": result.url,
|
||
"markdown": result.markdown,
|
||
"html": result.html,
|
||
"links": result.links,
|
||
"media": result.media,
|
||
}
|
||
|
||
async def crawl_batch(urls: list[str]):
|
||
"""批量抓取多个 URL"""
|
||
browser_config = BrowserConfig(headless=True)
|
||
run_config = CrawlerRunConfig(cache_mode=CacheMode.BYPASS)
|
||
|
||
async with AsyncWebCrawler(config=browser_config) as crawler:
|
||
results = await crawler.arun_many(urls=urls, config=run_config)
|
||
return [{"url": r.url, "markdown": r.markdown} for r in results]
|
||
|
||
async def crawl_site(base_url: str, max_pages: int = 20):
|
||
"""深度爬取整个站点"""
|
||
browser_config = BrowserConfig(headless=True)
|
||
run_config = CrawlerRunConfig(
|
||
cache_mode=CacheMode.BYPASS,
|
||
max_pages=max_pages,
|
||
)
|
||
|
||
async with AsyncWebCrawler(config=browser_config) as crawler:
|
||
results = await crawler.arun(url=base_url, config=run_config)
|
||
return results
|
||
```
|
||
|
||
**关键配置:**
|
||
- `BrowserConfig(headless=True, browser_type="chromium")` — 默认 Chromium
|
||
- `CrawlerRunConfig(css_selector="article")` — 只提取特定 CSS 区域
|
||
- `CrawlerRunConfig(extracted_content_type="json")` — 配合 schema 做结构化提取
|
||
- `CrawlerRunConfig(cache_mode=CacheMode.ENABLED)` — 启用缓存加速重复抓取
|
||
|
||
**注意:**crawl4ai 使用的 lxml 版本可能与 scrapling 冲突,但实际影响可忽略(6.x 向下兼容 5.x API)。
|
||
|
||
---
|
||
|
||
## 3. Scrapling — 反爬绕过专用
|
||
|
||
**适用场景:** 被 Cloudflare/DataDok/PerimeterX 等反爬系统保护的网站。自动模拟真实浏览器指纹。
|
||
|
||
```python
|
||
from scrapling import Fetcher, StealthyFetcher, PlayWrightFetcher
|
||
|
||
# 方式1:基础 Fetcher(轻量级,自动处理简单反爬)
|
||
page = Fetcher.get("https://example.com/protected")
|
||
print(page.status, page.text[:200])
|
||
|
||
# 方式2:StealthyFetcher(中等反爬,使用 curl_cffi 模拟浏览器指纹)
|
||
page = StealthyFetcher.fetch("https://example.com/protected")
|
||
# 可传参:headless=True, wait_selector="css:.content", network_idle=True
|
||
|
||
# 方式3:PlayWrightFetcher(最强反爬,真实浏览器 + stealth 插件)
|
||
page = PlayWrightFetcher.fetch(
|
||
"https://example.com/protected",
|
||
headless=True,
|
||
wait_selector="css:.main-content",
|
||
network_idle=True,
|
||
timeout=30000
|
||
)
|
||
|
||
# 提取数据 — CSS 选择器
|
||
items = page.css(".product-item")
|
||
for item in items:
|
||
title = item.css_first(".title").text()
|
||
price = item.css_first(".price").text()
|
||
|
||
# 提取数据 — XPath
|
||
links = page.xpath("//a[@class='product-link']")
|
||
|
||
# 自动适配网页结构(智能匹配)
|
||
page = Fetcher.get("https://example.com")
|
||
similar = page.find("product-card", score_threshold=0.5)
|
||
```
|
||
|
||
**三种引擎对比:**
|
||
| 引擎 | 速度 | 反爬能力 | JS渲染 | 适用 |
|
||
|------|------|---------|--------|------|
|
||
| Fetcher | ⚡最快 | 低 | ❌ | 静态页面 |
|
||
| StealthyFetcher | 🚀快 | 中高 | ❌ | Cloudflare等 |
|
||
| PlayWrightFetcher | 🐌较慢 | 最高 | ✅ | 重度反爬+JS |
|
||
|
||
---
|
||
|
||
## 4. CamouFox — 隐身浏览器(专治登录墙)
|
||
|
||
**适用场景:** 需要登录才能访问的内容、复杂的反爬检测、人机验证。基于 Firefox,指纹伪装极强。
|
||
|
||
```python
|
||
from camoufox.sync_api import Camoufox
|
||
|
||
# 基础用法
|
||
with Camoufox(headless=True) as browser:
|
||
page = browser.new_page()
|
||
page.goto("https://example.com/login")
|
||
page.fill("#username", "myuser")
|
||
page.fill("#password", "mypass")
|
||
page.click("button[type=submit]")
|
||
page.wait_for_load_state("networkidle")
|
||
|
||
# 登录后抓取内容
|
||
content = page.content()
|
||
print(content[:500])
|
||
|
||
# 异步用法
|
||
from camoufox.async_api import AsyncCamoufox
|
||
|
||
async def stealth_browse(url: str):
|
||
async with AsyncCamoufox(headless=True) as browser:
|
||
page = await browser.new_page()
|
||
await page.goto(url)
|
||
await page.wait_for_load_state("networkidle")
|
||
return await page.content()
|
||
|
||
# 代理模式(防 IP 封锁)
|
||
with Camoufox(
|
||
headless=True,
|
||
proxy={"server": "http://proxy:port", "username": "u", "password": "p"}
|
||
) as browser:
|
||
page = browser.new_page()
|
||
page.goto("https://example.com")
|
||
|
||
# 反指纹增强选项
|
||
with Camoufox(
|
||
headless=True,
|
||
humanize=True, # 模拟人类操作节奏
|
||
os=["windows"], # 伪装为 Windows 系统
|
||
geoip=True, # 自动匹配地理IP
|
||
) as browser:
|
||
page = browser.new_page()
|
||
page.goto("https://example.com")
|
||
```
|
||
|
||
**CamouFox vs Playwright 对比:**
|
||
| 特性 | Playwright | CamouFox |
|
||
|------|-----------|----------|
|
||
| 浏览器引擎 | Chromium | Firefox |
|
||
| 反指纹 | 无内置 | 内置强伪装 |
|
||
| 登录墙 | 需要手动设置 | 自然绕过 |
|
||
| Cloudflare | 偶尔被检测 | 基本不检测 |
|
||
| 速度 | 快 | 略慢 |
|
||
|
||
**浏览器二进制管理:**
|
||
- 安装/更新:`python -m camoufox fetch`
|
||
- 当前版本:v135.0.1-beta.24
|
||
|
||
---
|
||
|
||
## 5. AutoCLI — Chrome 登录态复用 + AI 生成适配器
|
||
|
||
**适用场景:** 已在 Chrome 浏览器登录的站点,直接复用 Cookie 抓取数据,无需管理 API Key。55+ 站点 333 个内置命令(Twitter/X、Reddit、Bilibili、知乎、小红书、YouTube 等)。AI 可自动生成新站点适配器。
|
||
|
||
**GitHub:** [nashsu/AutoCLI](https://github.com/nashsu/AutoCLI) ⭐2.6k | Rust 单二进制 4.7MB | Apache 2.0
|
||
|
||
**安装(一行命令):**
|
||
```bash
|
||
curl -fsSL https://raw.githubusercontent.com/nashsu/autocli/main/scripts/install.sh | sh
|
||
```
|
||
|
||
**Chrome 扩展设置(浏览器类命令必需):**
|
||
1. 从 [Releases](https://github.com/nashsu/autocli/releases/latest) 下载 `autocli-chrome-extension.zip`
|
||
2. Chrome → `chrome://extensions` → 开发者模式 → 加载已解压扩展
|
||
3. 扩展自动连接 autocli daemon
|
||
|
||
**常用命令:**
|
||
```bash
|
||
# 查看所有命令
|
||
autocli --help
|
||
autocli hackernews --help
|
||
|
||
# 公开 API(无需浏览器)
|
||
autocli hackernews top --limit 10
|
||
autocli hackernews top --limit 5 --format json
|
||
|
||
# 需要浏览器+登录态
|
||
autocli bilibili hot --limit 20
|
||
autocli twitter search "rust lang" --limit 10
|
||
autocli xiaohongshu search "关键词"
|
||
|
||
# AI 命令 — 自动生成适配器
|
||
autocli auth # 首次认证 autocli.ai
|
||
autocli generate --ai # AI 分析当前页面生成适配器
|
||
autocli search https://example.com # 搜索已有适配器
|
||
autocli explore <url> # 分析网站 API
|
||
autocli cascade <url> # 探测认证策略
|
||
|
||
# 多格式输出
|
||
autocli bilibili hot --format json|yaml|csv|markdown
|
||
|
||
# 诊断
|
||
autocli doctor
|
||
```
|
||
|
||
**v0.3.2 新功能:** Chrome 扩展可视化选数据 — 在页面上点选元素,AI 自动扩展相关字段并生成完整抓取规则。
|
||
|
||
**与其他工具的关键区别:**
|
||
- **无需 API Key** — 直接复用 Chrome 已有登录态,其他工具都需要自己管理登录/cookie
|
||
- **CLI 原生** — 命令行直接调用,天然适合 AI Agent 集成
|
||
- **AI 生成** — 自动分析任意网站创建适配器,其他工具需手动编写选择器
|
||
- **速度极快** — Rust 实现,比 Node.js 原版快 12x
|
||
|
||
**⚠️ 限制:**
|
||
- 服务器环境无 Chrome 桌面 → 无法使用 Chrome 扩展和浏览器类命令(需有桌面浏览器)
|
||
- 适合用户本地电脑运行,或在 VNC/远程桌面环境中使用
|
||
- 公开 API 命令(hackernews 等)可在服务器直接用
|
||
|
||
---
|
||
|
||
## 快速选型指南
|
||
|
||
| 需求 | 工具 | 一行代码 |
|
||
|------|------|---------|
|
||
| 读一篇文章 | Jina Reader | `curl -s https://r.jina.ai/URL` |
|
||
| 批量抓100页 | Crawl4AI | `AsyncWebCrawler().arun_many(urls)` |
|
||
| 反爬网站 | Scrapling | `StealthyFetcher.fetch(url)` |
|
||
| 需要登录 | CamouFox / AutoCLI | `Camoufox(headless=True)` / `autocli x search "key"` |
|
||
| JS重页面 | Crawl4AI / Scrapling PW | 都可处理JS |
|
||
| 速度优先 | Jina Reader | 无需渲染,最快 |
|
||
| 已登录Chrome直接抓 | AutoCLI | `autocli <site> <cmd>` |
|
||
| AI自动生成抓取规则 | AutoCLI | `autocli generate --ai` |
|
||
|
||
## 免费代理获取(补充)
|
||
|
||
proxy-tools.com 等网站的端口被 reCAPTCHA/付费墙保护,免费用户拿不到。替代方案:
|
||
- **proxyscrape.com 免费 API**(无需 key):
|
||
- `https://api.proxyscrape.com/v2/?request=displayproxies&protocol=socks5&timeout=5000&country=ru`
|
||
- protocol 参数:http / socks5 / socks4
|
||
- country 参数:ISO 两字母代码,留空=全球
|
||
- 返回纯文本 `IP:PORT` 列表
|
||
- 免费代理可用率约 5-6%,寿命短(小时~天级别),需定期刷新
|
||
|
||
## 已知问题
|
||
|
||
1. **lxml 版本冲突**:Crawl4AI 要求 lxml~=5.3,Scrapling 要求 lxml>=6.0。实际运行中 lxml 6.x API 向下兼容 5.x,不影响使用。
|
||
2. **Jina Reader 限速**:免费版约 20 req/min,可加 `X-No-Cache: true` 绕过缓存(但消耗更快)。大批量用 Crawl4AI 替代。
|
||
3. **CamouFox 启动慢**:Firefox 启动比 Chromium 慢约 2-3 秒,session 复用可缓解。
|
||
4. **Scrapling DynamicFetcher 缺依赖**:需额外安装 `msgspec`(`pip install msgspec`),否则 import 报错。
|
||
5. **curl socks5h/socks4a 不支持**:本系统 curl 版本不支持 `--proxy socks5h` 或 `--proxy socks4a`,改用 `--socks5` / `--socks4` 参数代替。
|
||
6. **Scrapling PlayWrightFetcher 已更名**:0.4.7 版本中叫 `DynamicFetcher`,不是 `PlayWrightFetcher`。
|
||
7. **AutoCLI 服务器限制**:服务器无 Chrome 桌面环境,浏览器类命令(bilibili、twitter 等需 Cookie 的)不可用;公开 API 命令(hackernews 等)正常。用户本地电脑或 VNC 环境可完整使用。
|