shahar99s/link-fetchers
GitHub: shahar99s/link-fetchers
一个统一接口的 Python 库,能自动识别 URL 来源并从二十多种热门文件分享平台获取元数据或下载文件。
Stars: 1 | Forks: 0
# link-fetchers
一个用于从热门文件分享服务获取文件元数据和下载的 Python 库。可自动从 URL 检测提供商,并路由到正确的 fetcher。
基于 `httporchestrator` 引擎:https://github.com/shahar99s/httporchestrator.py
## 支持的提供商
| 提供商 | 示例 URL | 备注 |
|---|---|---|
| 4Shared | `https://www.4shared.com/s/...` | |
| Box | `https://app.box.com/file/...` | 私有文件需要 OAuth2;参见 [Box](#box) |
| Box (shared link) | `https://app.box.com/s/...` | 无需认证 |
| ChatGPT | `https://chatgpt.com/c/...` / `https://chat.openai.com/share/...` | |
| Dropbox Transfer | `https://www.dropbox.com/t/...` | |
| FileCat | `https://filecat.net/f/...` | 支持获取元数据;下载需要有效的 `captcha_token` |
| Filemail | `https://www.filemail.com/d/...` | |
| GoFile | `https://gofile.io/d/...` | 支持密码保护的文件 |
| Internxt Send | `https://send.internxt.com/d/...` | 支持 SendGrid 追踪链接 |
| Limewire | `https://limewire.com/d/...` | |
| MediaFire | `https://www.mediafire.com/file/...` | |
| Mega | `https://mega.nz/file/...` | |
| SendAnywhere | `https://send-anywhere.com/web/downloads/...` | |
| SendGB | `https://sendgb.com/...` | |
| FromSmash | `https://fromsmash.com/...` | |
| TeraBox | `https://1024terabox.com/s/...` | |
| Tresorit Send | `https://send.tresorit.com/...#KEY` | 支持元数据/开放链接;公开文件为端到端加密 |
| TransferNow | `https://www.transfernow.net/dl/...` | |
| TransferXL | `https://transferxl.com/download/...` | |
| Turbobit | `https://turbobit.net/...` / `https://trbt.cc/...` | 免费下载;可能设有 captcha 拦截 |
| WeTransfer | `https://wetransfer.com/downloads/...` / `https://we.tl/...` | |
| Wormhole | `https://wormhole.app/...#KEY` | 端到端加密;密钥必须包含在 URL 片段中 |
## 安装说明
```
pip install .
```
依赖项通过 [Poetry](https://python-poetry.org/) 进行管理:
```
poetry install
```
## CLI
```
link-fetchers [options]
```
| 选项 | 默认值 | 描述 |
|---|---|---|
| `--mode info\|fetch\|force-fetch` | `fetch` | 操作模式 |
| `--save-path DIR` | 当前目录 | 保存下载文件的目录 |
| `--log-details` | 关闭 | 启用详细的 JSON 请求/响应日志记录 |
| `--retry-times N` | `3` | 针对临时错误的冲试次数 |
| `--retry-interval SECS` | `2.0` | 两次重试之间的等待秒数 |
| `--impersonate TARGET` | | 要模拟的 TLS 指纹(例如 `chrome131`) |
| `--opt KEY=VALUE` | | 特定于提供商的选项,可重复使用 |
**示例:**
```
# 仅获取 metadata
link-fetchers "https://gofile.io/d/SXwLDt" --mode info
# 下载到特定目录
link-fetchers "https://wetransfer.com/downloads/..." --save-path ./downloads
# 受密码保护的 GoFile 链接
link-fetchers "https://gofile.io/d/SXwLDt" --opt password=secret
# 使用 OAuth2 credentials 的 Box private file
link-fetchers "https://app.box.com/file/123" --opt client_id=ID --opt client_secret=SECRET
# 使用已解决的 captcha token 进行 FileCat 下载
link-fetchers "https://filecat.net/f/vV0NeF" --opt captcha_token=TOKEN
```
## 快速开始(Python API)
```
from link_fetchers import create_fetcher, Mode
fetcher = create_fetcher(
"https://www.4shared.com/s/fkEvKTDlWge",
mode=Mode.FETCH,
)
fetcher.run()
```
## 模式
| 模式 | 描述 |
|---|---|
| `Mode.INFO` | 仅获取文件元数据(名称、大小、类型)——不下载 |
| `Mode.FETCH` | 如果直接链接可用,则下载文件 |
| `Mode.FORCE_FETCH` | 无论可用性信号如何,均强制下载 |
## 选项
所有 fetcher 均接受以下关键字参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| `mode` | `Mode` | `Mode.FETCH` | 操作模式 |
| `headers` | `dict` | | 包含在请求中的额外 HTTP 标头 |
| `cookies` | `dict \| str` | | 要发送的 Cookies(合并到 `Cookie` 标头中) |
| `impersonate` | `str \| dict` | | 要模拟的 TLS 指纹(例如 `"chrome124"`) |
| `save_path` | `str \| Path` | cwd | 保存下载文件的目录 |
| `log_details` | `bool` | `False` | 启用详细的 JSON 请求/响应日志记录 |
| `retry_times` | `int` | `3` | 针对临时错误的重试次数(`0` 为禁用) |
| `retry_interval` | `float` | `2.0` | 两次重试之间的秒数 |
### 模拟
传递浏览器字符串或详细的 dict 以绕过基于 TLS 的机器人检测:
```
fetcher = create_fetcher(
url,
impersonate={
"browser": "Chrome",
"version": "131",
"os": "Windows",
},
)
```
简写字符串形式:`impersonate="chrome124"`。
## 示例
### 仅获取元数据
```
from link_fetchers import create_fetcher, Mode
fetcher = create_fetcher("https://mega.nz/file/cH51DYDR#...", mode=Mode.INFO)
result = fetcher.run()
print(result.summary)
```
### 将文件下载到特定目录
```
from link_fetchers import create_fetcher, Mode
from pathlib import Path
fetcher = create_fetcher(
"https://wetransfer.com/downloads/TID/SEC123",
mode=Mode.FETCH,
save_path=Path("./downloads"),
)
fetcher.run()
```
### 带有身份验证副本的 MediaFire
某些提供商支持可选的凭据,以解锁额外的访问权限:
```
fetcher = create_fetcher(
"https://www.mediafire.com/file/abc123/file",
mode=Mode.FETCH,
email="user@example.com",
password="secret",
)
fetcher.run()
## Project Structure
```
link_fetchers/
├── __init__.py # 公共 API:BaseFetcher, create_fetcher, Mode
├── base_fetcher.py # 所有 fetcher 的基类
├── fetcher_registry.py # 自动发现工厂
├── utils.py # 共享工具和枚举
├── tls_client.py # curl-cffi TLS 模拟客户端
└── fetchers/ # 提供商实现
├── box_fetcher.py
├── chatgpt_fetcher.py
├── dropbox_transfer_fetcher.py
├── filemail_fetcher.py
├── fourshared_fetcher.py
├── gofile_fetcher.py
├── limewire_fetcher.py
├── mediafire_fetcher.py
├── mega_fetcher.py
├── sendanywhere_fetcher.py
├── sendgb_fetcher.py
├── smash_fetcher.py
├── terabox_fetcher.py
├── transfernow_fetcher.py
├── transferxl_fetcher.py
├── turbobit_fetcher.py
├── wetransfer_fetcher.py
└── wormhole_fetcher.py
tests/
└── link_fetchers/
├── test_fetcher_factories.py # 注册表和 URL 匹配测试
├── test_fetchers.py # 各提供商单元测试
├── test_runner_state.py # BaseFetcher 生命周期测试
└── test_utils.py # 工具函数测试
```
## 添加新的 Provider
1. Create `link_fetchers/fetchers/myprovider_fetcher.py`.
2. Define a class ending with `Fetcher` that extends `BaseFetcher`.
3. Implement `is_relevant_url(url)` as a `@classmethod`.
4. Set `NAME` and `BASE_URL` class attributes.
5. Implement `build_info_steps()` and optionally `build_fetch_steps()` using `httporchestrator` request steps.
The registry discovers and registers it automatically — no other changes needed.
```python
from link_fetchers.base_fetcher import BaseFetcher
class MyProviderFetcher(BaseFetcher):
NAME = "MyProvider"
BASE_URL = "https://myprovider.com"
@classmethod
def is_relevant_url(cls, url: str) -> bool:
return "myprovider.com" in url
def build_info_steps(self):
...
```
## 运行测试
```
pytest
```
## 许可证
Apache 2.0 — 参见 [LICENSE](LICENSE)。
标签:API集成, Python, Web爬虫, 可观测性, 安全规则引擎, 文件下载, 文件分享, 无后门, 网络调试, 自动化, 逆向工具