arulmozhiv-youtube-scrapper

TotalClaw 作者 totalclaw

基于浏览器的 YouTube 频道发现与抓取工具,支持多区域配置与住宅代理。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw skills install shop:totalclaw:totalclaw~arulmozhiv-youtube-scrapper
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~arulmozhiv-youtube-scrapper/file -o arulmozhiv-youtube-scrapper.md
## 概述(中文)

基于浏览器的 YouTube 频道发现与抓取工具,支持多区域配置与住宅代理。

## 技能正文

# YouTube 频道抓取器

基于浏览器的 YouTube 频道发现与抓取工具。

> 属于 **[ScrapeClaw](https://www.scrapeclaw.cc/)** — 一套生产就绪的智能体化社媒抓取工具,覆盖 YouTube、YouTube、X/Twitter 与 Facebook,基于 Python 与 Playwright 构建,无需 API 密钥。

```yaml
---
name: youtube-scrapper
description: Discover and scrape YouTube channels from your browser.
emoji: 📺
version: 1.0.2
author: influenza
tags:
  - youtube
  - scraping
  - social-media
  - channel-discovery
  - influencer-discovery
metadata:
  clawdbot:
    requires:
      bins:
        - python3
        - chromium

    config:
      stateDirs:
        - data/output
        - data/queue
        - thumbnails
      outputFormats:
        - json
        - csv
---
```

## 概述

本技能提供两阶段 YouTube 抓取系统:

1. **频道发现** — 通过 Google 搜索发现 YouTube 频道(基于浏览器,无需 API 密钥)
2. **浏览器抓取** — 使用 Playwright 与反检测抓取公开频道数据(无需登录)

## 功能

- 🔍  - 按地区与类别发现 YouTube 频道
- 🌐  - 完整浏览器模拟以实现精准抓取
- 🛡️  - 浏览器指纹、人类行为模拟与隐身脚本
- 📊  - 频道信息、订阅、播放、视频、互动数据与媒体
- 💾  - JSON 导出并下载缩略图
- 🔄  - 恢复中断的抓取会话
- ⚡  - 自动跳过不可用频道与低订阅频道
- 🌍  - 内置 4 家住宅代理支持
- 🗺️  - 美国、英国、欧洲、印度、海湾与东亚的区域配置

## 用法

### 智能体工具接口

用于 OpenClaw 智能体集成时,本技能提供 JSON 输出:

```bash
# Discover YouTube channels (returns JSON queue)
python scripts/youtube_channel_discovery.py --categories tech --locations India

# Scrape from a queue file
python scripts/youtube_channel_scraper.py --queue data/queue/your_queue_file.json

# Full orchestration — discover + scrape in one go
python scripts/youtube_orchestrator.py --config resources/scraper_config_ind.json
```

## 输出数据

### 频道数据结构

```json
{
  "channel_name": "Marques Brownlee",
  "channel_url": "https://www.youtube.com/@mkbhd",
  "subscribers": 19200000,
  "total_views": 4500000000,
  "video_count": 1800,
  "description": "MKBHD: Quality Tech Videos...",
  "joined_date": "Mar 21, 2008",
  "country": "United States",
  "profile_pic_url": "https://...",
  "profile_pic_local": "thumbnails/mkbhd/profile_abc123.jpg",
  "banner_url": "https://...",
  "banner_local": "thumbnails/mkbhd/banner_def456.jpg",
  "influencer_tier": "mega",
  "category": "tech",
  "scrape_location": "New York",
  "scraped_at": "2026-02-17T12:00:00",
  "recent_videos": [
    {
      "title": "Galaxy S26 Ultra Review",
      "url": "https://www.youtube.com/watch?v=...",
      "views": 5200000,
      "published": "2 days ago",
      "duration": "14:32",
      "thumbnail_url": "https://...",
      "thumbnail_local": "thumbnails/mkbhd/video_0_ghi789.jpg"
    }
  ]
}
```

### 队列文件结构

```json
{
  "location": "India",
  "category": "tech",
  "total": 20,
  "channels": ["@channel1", "@channel2", "..."],
  "completed": ["@channel1"],
  "failed": {"@channel3": "not_found"},
  "current_index": 2,
  "created_at": "2026-02-17T12:00:00",
  "source": "google_search"
}
```

### 网红层级

| 层级  | 订阅数范围          |
|-------|---------------------|
| nano  | < 1,000             |
| micro | 1,000 – 10,000      |
| mid   | 10,000 – 100,000    |
| macro | 100,000 – 1M        |
| mega  | > 1,000,000         |

### 文件输出

- **队列文件**:`data/queue/{region}/{location}_{category}_{timestamp}.json`
- **抓取数据**:`data/output_{region}/{channel_name}.json`
- **缩略图**:`thumbnails_{region}/{channel}/profile_*.jpg`、`thumbnails_{region}/{channel}/video_*.jpg`
- **进度**:`data/progress/discovery_progress_{region}.json`

## 配置

区域配置文件位于 `resources/`:

```
resources/scraper_config_us.json
resources/scraper_config_uk.json
resources/scraper_config_eur.json
resources/scraper_config_ind.json
resources/scraper_config_gulf.json
resources/scraper_config_east.json
```

配置示例(`resources/scraper_config_ind.json`):

```json
{
  "proxy": {
    "enabled": false,
    "provider": "brightdata",
    "country": "",
    "sticky": true,
    "sticky_ttl_minutes": 10
  },
  "categories": [
    "gaming", "tech", "beauty", "fashion", "fitness",
    "food", "travel", "music", "education", "comedy",
    "lifestyle", "cooking", "diy", "art", "finance",
    "health", "entertainment"
  ],
  "locations": [
    "India", "Mumbai", "Delhi", "Bangalore", "Hyderabad",
    "Chennai", "Kolkata", "Pune", "Ahmedabad", "Jaipur"
  ],
  "max_videos_to_scrape": 6,
  "headless": false,
  "results_per_search": 20,
  "search_delay": [3, 7],
  "scrape_delay": [2, 5],
  "rate_limit_wait": 60,
  "max_retries": 3
}
```

## 应用的过滤器

抓取器自动过滤:

- ❌ 不可用或已终止的频道
- ❌ 订阅 < 500 的频道(可配置)
- ❌ 不存在的频道 URL
- ❌ 已抓取条目(去重)
- ❌ 被限流请求(自动退避重试)

## 反检测

抓取器使用多种反检测技术:

- **浏览器指纹** — 轮换指纹配置(视口、User-Agent、时区、WebGL 等)
- **隐身 JavaScript** — 隐藏 `navigator.webdriver`,伪造插件/语言/硬件,canvas 噪声,伪造 `chrome` 对象
- **人类行为模拟** — 随机延迟、鼠标移动、滚动模式
- **网络随机化** — 请求间可变时序
- **请求拦截** — 阻止已知指纹与跟踪脚本

## 故障排除

### 未发现频道

- 尝试不同的地区/类别组合
- 检查 Google 搜索是否返回 CAPTCHA 页面
- 使用 `--headless false` 进行可视化调试

### 速率限制

- 降低抓取速度(在配置中增加延迟)
- 在非高峰时段运行
- **使用住宅代理**(见下文)

### 浏览器崩溃

- 编排器每 50 个频道自动重启浏览器
- 中断的抓取可恢复 — 队列文件自动跟踪进度

---

## 🌐 住宅代理支持

### 为何使用住宅代理?

大规模运行抓取器时**若不使用**住宅代理,IP 很快会被封禁。以下是代理对长期抓取至关重要的原因:

| 优势 | 说明 |
|-----------|-------------|
| **Avoid IP Bans** | Residential IPs look like real household users, not data-center bots. YouTube is far less likely to flag them. |
| **自动 IP 轮换** | 每次请求(或会话)获得新 IP,限流不会堆积在同一地址。 |
| **地理定向** | 通过特定国家/城市路由流量,使抓取内容与目标受众地区一致。 |
| **粘性会话** | 在可配置时间窗口(如 10 分钟)内保持同一 IP — 对维持一致浏览会话至关重要。 |
| **Higher Success Rate** | Rotating residential IPs deliver 95%+ success rates compared to ~30% with data-center proxies on YouTube. |
| **Long-Running Scrapes** | Scrape thousands of channels over hours or days without interruption. |
| **并发抓取** | 在不同 IP 上同时运行多个浏览器实例。 |

### 推荐代理提供商

我们与顶级住宅代理提供商有联盟合作。使用以下链接可支持本技能的持续开发:

| 提供商 | 最适合 | 注册 |
|----------|----------|---------|
| **Bright Data** | 全球最大网络,7200 万+ IP,企业级 | 👉 [**Get Bright Data**](https://get.brightdata.com/o1kpd2da8iv4) |
| **IProyal** | 按量付费,195+ 国家,流量不过期 | 👉 [**Get IProyal**](https://iproyal.com/?r=ScrapeClaw) |
| **Storm Proxies** | 快速可靠,开发者友好 API,价格有竞争力 | 👉 [**Get Storm Proxies**](https://stormproxies.com/clients/aff/go/scrapeclaw) |
| **NetNut** | ISP 级网络,5200 万+ IP,直连 | 👉 [**Get NetNut**](https://netnut.io?ref=mwrlzwv) |

### 配置步骤

#### 1. 获取代理凭证

在以上任一提供商注册后获取:
- **用户名**(来自提供商控制台)
- **密码**(来自提供商控制台)
- **Host** 与 **Port** 按提供商预配置(或使用自定义)

#### 2. 通过环境变量配置

```bash
export PROXY_ENABLED=true
export PROXY_PROVIDER=brightdata    # brightdata | iproyal | stormproxies | netnut | custom
export PROXY_USERNAME=your_user
export PROXY_PASSWORD=your_pass
export PROXY_COUNTRY=us             # optional: two-letter country code
export PROXY_STICKY=true            # optional: keep same IP per session
```

#### 3. 各提供商 Host/Port 默认值

设置 `provider` 名称后会自动配置:

| 提供商 | Host | Port |
|----------|------|------|
| Bright Data | `brd.superproxy.io` | `22225` |
| IProyal | `proxy.iproyal.com` | `12321` |
| Storm Proxies | `rotating.stormproxies.com` | `9999` |
| NetNut | `gw-resi.netnut.io` | `5959` |

若套餐使用不同网关,可用 `PROXY_HOST` / `PROXY_PORT` 环境变量覆盖。

#### 4. 自定义代理提供商

其他代理服务请将 provider 设为 `custom` 并手动提供 host/port:

```json
{
  "proxy": {
    "enabled": true,
    "provider": "custom",
    "host": "your.proxy.host",
    "port": 8080,
    "username": "user",
    "password": "pass"
  }
}
```

### 使用代理运行抓取器

配置完成后,抓取器自动使用代理 — 无需额外参数:

```bash
# Discover and scrape as usual — proxy is applied automatically
python scripts/youtube_orchestrator.py --config resources/scraper_config_ind.json

# The log will confirm proxy is active:
# INFO - Proxy enabled: <ProxyManager provider=brightdata enabled host=brd.superproxy.io:22225>
# INFO - Browser using proxy: brightdata → brd.superproxy.io:22225
```

### 以编程方式使用 Proxy Manager

```python
from proxy_manager import ProxyManager

# From config (auto-reads config from resources/)
pm = ProxyManager.from_config()

# From environment variables
pm = ProxyManager.from_env()

# Manual construction
pm = ProxyManager(
    provider="brightdata",
    username="your_user",
    password="your_pass",
    country="us",
    sticky=True
)

# For Playwright browser context
proxy = pm.get_playwright_proxy()
# → {"server": "http://brd.superproxy.io:22225",