ipclick 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ipclick-0.1.0/LICENSE +21 -0
- ipclick-0.1.0/PKG-INFO +279 -0
- ipclick-0.1.0/README.md +256 -0
- ipclick-0.1.0/pyproject.toml +38 -0
- ipclick-0.1.0/src/ipclick/__init__.py +25 -0
- ipclick-0.1.0/src/ipclick/__main__.py +11 -0
- ipclick-0.1.0/src/ipclick/adapters/__init__.py +109 -0
- ipclick-0.1.0/src/ipclick/adapters/base.py +183 -0
- ipclick-0.1.0/src/ipclick/adapters/curl_cffi_adapter.py +163 -0
- ipclick-0.1.0/src/ipclick/adapters/httpx_adapter.py +172 -0
- ipclick-0.1.0/src/ipclick/cli/__init__.py +13 -0
- ipclick-0.1.0/src/ipclick/cli/main.py +146 -0
- ipclick-0.1.0/src/ipclick/config_loader/__init__.py +10 -0
- ipclick-0.1.0/src/ipclick/config_loader/loader.py +59 -0
- ipclick-0.1.0/src/ipclick/configs/__init__.py +7 -0
- ipclick-0.1.0/src/ipclick/configs/default_config.toml +126 -0
- ipclick-0.1.0/src/ipclick/dto/__init__.py +13 -0
- ipclick-0.1.0/src/ipclick/dto/models.py +265 -0
- ipclick-0.1.0/src/ipclick/dto/proto/__init__.py +7 -0
- ipclick-0.1.0/src/ipclick/dto/proto/task.proto +92 -0
- ipclick-0.1.0/src/ipclick/dto/proto/task_pb2.py +59 -0
- ipclick-0.1.0/src/ipclick/dto/proto/task_pb2_grpc.py +109 -0
- ipclick-0.1.0/src/ipclick/dto/response.py +181 -0
- ipclick-0.1.0/src/ipclick/sdk.py +204 -0
- ipclick-0.1.0/src/ipclick/server.py +183 -0
- ipclick-0.1.0/src/ipclick/services/__init__.py +12 -0
- ipclick-0.1.0/src/ipclick/services/task_service.py +268 -0
- ipclick-0.1.0/src/ipclick/utils/__init__.py +63 -0
- ipclick-0.1.0/src/ipclick/utils/logger.py +57 -0
ipclick-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 元气码农少女酱
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ipclick-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ipclick
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: IPClick Tool
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: 元气码农少女酱
|
|
8
|
+
Author-email: 1276162429@qq.com
|
|
9
|
+
Requires-Python: >=3.14
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: click (>=8.3.1,<9.0.0)
|
|
14
|
+
Requires-Dist: curl-cffi (>=0.13.0,<0.14.0)
|
|
15
|
+
Requires-Dist: fake-useragent (>=2.2.0,<3.0.0)
|
|
16
|
+
Requires-Dist: grpcio (>=1.76.0,<2.0.0)
|
|
17
|
+
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
18
|
+
Requires-Dist: protobuf (>=6.33.2,<7.0.0)
|
|
19
|
+
Project-URL: Bug Tracker, https://github.com/yuanqimanong/IPClick/issues
|
|
20
|
+
Project-URL: Homepage, https://github.com/yuanqimanong/IPClick
|
|
21
|
+
Project-URL: Repository, https://github.com/yuanqimanong/IPClick
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# IPClick
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
> IPClick 名字灵感来源于动画《Link Click》(时光代理人)。正如时光代理人穿梭于不同的时空执行任务,IPClick 帮助您将 HTTP 请求分发到不同的节点高效执行。
|
|
29
|
+
|
|
30
|
+
## 📖 简介
|
|
31
|
+
|
|
32
|
+
IPClick 是一个轻量级、高性能的分布式 HTTP 请求代理工具,基于 gRPC 协议构建。它提供了统一的请求接口,支持多种 HTTP
|
|
33
|
+
客户端适配器,帮助开发者更高效地处理网络请求。
|
|
34
|
+
|
|
35
|
+
## ✨ 特性
|
|
36
|
+
|
|
37
|
+
- **多适配器支持**:内置 `curl_cffi`、`httpx`、`requests` 等多种 HTTP 客户端适配器
|
|
38
|
+
- **浏览器指纹伪装**:基于 `curl_cffi` 实现浏览器指纹模拟,有效绑过反爬检测
|
|
39
|
+
- **gRPC 通信**:使用 gRPC 协议进行高效的客户端-服务端通信
|
|
40
|
+
- **代理支持**:灵活的代理配置,支持 HTTP/HTTPS/SOCKS 代理
|
|
41
|
+
- **自动重试**:内置请求重试机制,支持自定义重试策略和退避算法
|
|
42
|
+
- **命令行工具**:提供便捷的 CLI 工具,支持快速启动服务和测试请求
|
|
43
|
+
- **Docker 支持**:提供 Dockerfile,支持容器化部署
|
|
44
|
+
- **易于扩展**:模块化设计,便于添加新的适配器和功能
|
|
45
|
+
|
|
46
|
+
## 📦 安装
|
|
47
|
+
|
|
48
|
+
### 从 PyPI 安装
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install ipclick
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 从源码安装
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# 克隆仓库
|
|
58
|
+
git clone https://github.com/yuanqimanong/IPClick.git
|
|
59
|
+
cd IPClick
|
|
60
|
+
|
|
61
|
+
# 使用 Poetry 安装依赖
|
|
62
|
+
poetry install
|
|
63
|
+
|
|
64
|
+
# 或使用 pip 安装
|
|
65
|
+
pip install -e .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 🔧 系统要求
|
|
69
|
+
|
|
70
|
+
- Python >= 3.14
|
|
71
|
+
- 依赖库:
|
|
72
|
+
- curl-cffi >= 0.13.0
|
|
73
|
+
- grpcio >= 1.76.0
|
|
74
|
+
- protobuf >= 6.33.2
|
|
75
|
+
- click >= 8.3.1
|
|
76
|
+
- httpx >= 0.28.1
|
|
77
|
+
- fake-useragent >= 2.2.0
|
|
78
|
+
|
|
79
|
+
## 🚀 快速开始
|
|
80
|
+
|
|
81
|
+
### 启动服务端
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# 使用默认配置启动
|
|
85
|
+
ipclick run
|
|
86
|
+
|
|
87
|
+
# 指定端口和地址
|
|
88
|
+
ipclick run --host 0.0.0.0 --port 9527
|
|
89
|
+
|
|
90
|
+
# 使用自定义配置文件
|
|
91
|
+
ipclick run --config /path/to/config.yaml
|
|
92
|
+
|
|
93
|
+
# 显示详细日志
|
|
94
|
+
ipclick run --verbose
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 客户端使用
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from ipclick import Downloader, HttpMethod
|
|
101
|
+
|
|
102
|
+
# 创建下载器实例
|
|
103
|
+
downloader = Downloader()
|
|
104
|
+
|
|
105
|
+
# 发送 GET 请求
|
|
106
|
+
response = downloader.get("https://httpbin.org/ip")
|
|
107
|
+
print(response.text)
|
|
108
|
+
print(response.json())
|
|
109
|
+
|
|
110
|
+
# 发送带参数的请求
|
|
111
|
+
response = downloader.request(
|
|
112
|
+
method=HttpMethod.GET,
|
|
113
|
+
url="https://httpbin.org/get",
|
|
114
|
+
headers={"User-Agent": "IPClick/1.0"},
|
|
115
|
+
params={"key": "value"},
|
|
116
|
+
timeout=30
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# 检查请求是否成功
|
|
120
|
+
if response.is_success():
|
|
121
|
+
print(f"请求成功,耗时: {response.elapsed_ms}ms")
|
|
122
|
+
else:
|
|
123
|
+
print(f"请求失败: {response.error}")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 使用代理
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from ipclick import Downloader, ProxyConfig, HttpMethod
|
|
130
|
+
|
|
131
|
+
# 方式一:使用代理配置对象
|
|
132
|
+
proxy = ProxyConfig(
|
|
133
|
+
scheme="http",
|
|
134
|
+
host="proxy.example.com",
|
|
135
|
+
port=8080,
|
|
136
|
+
auth_key="username",
|
|
137
|
+
auth_password="password"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
response = downloader.request(
|
|
141
|
+
method=HttpMethod.GET,
|
|
142
|
+
url="https://httpbin.org/ip",
|
|
143
|
+
proxy=proxy
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# 方式二:使用代理 URL 字符串
|
|
147
|
+
response = downloader.request(
|
|
148
|
+
method=HttpMethod.GET,
|
|
149
|
+
url="https://httpbin.org/ip",
|
|
150
|
+
proxy="http://user:pass@proxy.example.com:8080"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# 方式三:使用配置文件中的代理(设置 proxy=True)
|
|
154
|
+
response = downloader.request(
|
|
155
|
+
method=HttpMethod.GET,
|
|
156
|
+
url="https://httpbin.org/ip",
|
|
157
|
+
proxy=True
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 使用全局下载器
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from ipclick import downloader
|
|
165
|
+
|
|
166
|
+
# 使用默认的全局下载器实例
|
|
167
|
+
response = downloader.get("https://httpbin.org/ip")
|
|
168
|
+
print(response.text)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## 📂 项目结构
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
IPClick/
|
|
175
|
+
├── src/
|
|
176
|
+
│ └── ipclick/
|
|
177
|
+
│ ├── __init__.py # 包入口,导出公共 API
|
|
178
|
+
│ ├── __main__.py # 模块入口
|
|
179
|
+
│ ├── sdk. py # SDK 客户端实现
|
|
180
|
+
│ ├── server.py # gRPC 服务端实现
|
|
181
|
+
│ ├── adapters/ # HTTP 客户端适配器
|
|
182
|
+
│ │ ├── base.py # 适配器基类
|
|
183
|
+
│ │ ├── curl_cffi_adapter.py
|
|
184
|
+
│ │ └── httpx_adapter.py
|
|
185
|
+
│ ├── cli/ # 命令行工具
|
|
186
|
+
│ │ └── main.py
|
|
187
|
+
│ ├── config_loader/ # 配置加载器
|
|
188
|
+
│ ├── configs/ # 默认配置文件
|
|
189
|
+
│ ├── dto/ # 数据传输对象
|
|
190
|
+
│ │ ├── models.py # 数据模型定义
|
|
191
|
+
│ │ ├── response.py # 响应对象
|
|
192
|
+
│ │ └── proto/ # Protobuf 定义
|
|
193
|
+
│ ├── services/ # gRPC 服务实现
|
|
194
|
+
│ └── utils/ # 工具模块
|
|
195
|
+
├── docker/ # Docker 相关文件
|
|
196
|
+
│ └── Dockerfile
|
|
197
|
+
├── examples/ # 示例代码
|
|
198
|
+
├── tests/ # 测试代码
|
|
199
|
+
├── pyproject.toml # 项目配置
|
|
200
|
+
└── README. md
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## ⚙️ 配置说明
|
|
204
|
+
|
|
205
|
+
### 服务端配置
|
|
206
|
+
|
|
207
|
+
| 配置项 | 说明 | 默认值 |
|
|
208
|
+
|----------------------|---------|-----------|
|
|
209
|
+
| `SERVER. host` | 服务绑定地址 | `0.0.0.0` |
|
|
210
|
+
| `SERVER.port` | 服务端口 | `9527` |
|
|
211
|
+
| `SERVER.max_workers` | 最大工作线程数 | `10` |
|
|
212
|
+
|
|
213
|
+
### 客户端配置
|
|
214
|
+
|
|
215
|
+
| 配置项 | 说明 | 默认值 |
|
|
216
|
+
|----------------------------|-----------|--------|
|
|
217
|
+
| `DOWNLOADER.timeout` | 默认超时时间(秒) | `60` |
|
|
218
|
+
| `DOWNLOADER.max_retries` | 最大重试次数 | `3` |
|
|
219
|
+
| `DOWNLOADER.retry_backoff` | 重试退避时间(秒) | `2. 0` |
|
|
220
|
+
|
|
221
|
+
## 🐳 Docker 部署
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# 构建镜像
|
|
225
|
+
cd docker
|
|
226
|
+
docker build -t ipclick .
|
|
227
|
+
|
|
228
|
+
# 运行容器
|
|
229
|
+
docker run -d -p 9527:9527 --name ipclick ipclick
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 📚 API 参考
|
|
233
|
+
|
|
234
|
+
### DownloadTask 参数
|
|
235
|
+
|
|
236
|
+
| 参数 | 类型 | 说明 |
|
|
237
|
+
|-------------------|------------------------|------------|
|
|
238
|
+
| `url` | `str` | 请求 URL(必填) |
|
|
239
|
+
| `method` | `HttpMethod` | HTTP 方法 |
|
|
240
|
+
| `headers` | `Dict` | 请求头 |
|
|
241
|
+
| `cookies` | `Dict/str` | Cookies |
|
|
242
|
+
| `params` | `Dict` | URL 查询参数 |
|
|
243
|
+
| `data` | `Any` | 表单数据 |
|
|
244
|
+
| `json` | `Dict` | JSON 数据 |
|
|
245
|
+
| `proxy` | `ProxyConfig/str/bool` | 代理配置 |
|
|
246
|
+
| `timeout` | `float` | 超时时间(秒) |
|
|
247
|
+
| `max_retries` | `int` | 最大重试次数 |
|
|
248
|
+
| `verify` | `bool` | 是否验证 SSL |
|
|
249
|
+
| `allow_redirects` | `bool` | 是否跟随重定向 |
|
|
250
|
+
| `impersonate` | `str` | 浏览器指纹伪装 |
|
|
251
|
+
|
|
252
|
+
### DownloadResponse 属性
|
|
253
|
+
|
|
254
|
+
| 属性 | 类型 | 说明 |
|
|
255
|
+
|---------------|---------|-----------|
|
|
256
|
+
| `status_code` | `int` | HTTP 状态码 |
|
|
257
|
+
| `headers` | `Dict` | 响应头 |
|
|
258
|
+
| `content` | `bytes` | 响应内容(二进制) |
|
|
259
|
+
| `text` | `str` | 响应内容(文本) |
|
|
260
|
+
| `url` | `str` | 最终 URL |
|
|
261
|
+
| `elapsed_ms` | `int` | 请求耗时(毫秒) |
|
|
262
|
+
| `error` | `str` | 错误信息 |
|
|
263
|
+
|
|
264
|
+
### DownloadResponse 方法
|
|
265
|
+
|
|
266
|
+
- `json()` - 解析 JSON 响应
|
|
267
|
+
- `is_success()` - 判断请求是否成功
|
|
268
|
+
- `raise_for_status()` - 状态码异常时抛出异常
|
|
269
|
+
|
|
270
|
+
## 🤝 贡献
|
|
271
|
+
|
|
272
|
+
欢迎贡献代码、报告问题或提出建议!请通过 [GitHub Issues](https://github.com/yuanqimanong/IPClick/issues)
|
|
273
|
+
或 [Pull Requests](https://github.com/yuanqimanong/IPClick/pulls) 参与项目开发。
|
|
274
|
+
|
|
275
|
+
## 📄 许可证
|
|
276
|
+
|
|
277
|
+
本项目采用 [MIT License](LICENSE) 开源许可证。
|
|
278
|
+
|
|
279
|
+
Copyright (c) 2025 元气码农少女酱
|
ipclick-0.1.0/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# IPClick
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
> IPClick 名字灵感来源于动画《Link Click》(时光代理人)。正如时光代理人穿梭于不同的时空执行任务,IPClick 帮助您将 HTTP 请求分发到不同的节点高效执行。
|
|
6
|
+
|
|
7
|
+
## 📖 简介
|
|
8
|
+
|
|
9
|
+
IPClick 是一个轻量级、高性能的分布式 HTTP 请求代理工具,基于 gRPC 协议构建。它提供了统一的请求接口,支持多种 HTTP
|
|
10
|
+
客户端适配器,帮助开发者更高效地处理网络请求。
|
|
11
|
+
|
|
12
|
+
## ✨ 特性
|
|
13
|
+
|
|
14
|
+
- **多适配器支持**:内置 `curl_cffi`、`httpx`、`requests` 等多种 HTTP 客户端适配器
|
|
15
|
+
- **浏览器指纹伪装**:基于 `curl_cffi` 实现浏览器指纹模拟,有效绑过反爬检测
|
|
16
|
+
- **gRPC 通信**:使用 gRPC 协议进行高效的客户端-服务端通信
|
|
17
|
+
- **代理支持**:灵活的代理配置,支持 HTTP/HTTPS/SOCKS 代理
|
|
18
|
+
- **自动重试**:内置请求重试机制,支持自定义重试策略和退避算法
|
|
19
|
+
- **命令行工具**:提供便捷的 CLI 工具,支持快速启动服务和测试请求
|
|
20
|
+
- **Docker 支持**:提供 Dockerfile,支持容器化部署
|
|
21
|
+
- **易于扩展**:模块化设计,便于添加新的适配器和功能
|
|
22
|
+
|
|
23
|
+
## 📦 安装
|
|
24
|
+
|
|
25
|
+
### 从 PyPI 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install ipclick
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 从源码安装
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# 克隆仓库
|
|
35
|
+
git clone https://github.com/yuanqimanong/IPClick.git
|
|
36
|
+
cd IPClick
|
|
37
|
+
|
|
38
|
+
# 使用 Poetry 安装依赖
|
|
39
|
+
poetry install
|
|
40
|
+
|
|
41
|
+
# 或使用 pip 安装
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 🔧 系统要求
|
|
46
|
+
|
|
47
|
+
- Python >= 3.14
|
|
48
|
+
- 依赖库:
|
|
49
|
+
- curl-cffi >= 0.13.0
|
|
50
|
+
- grpcio >= 1.76.0
|
|
51
|
+
- protobuf >= 6.33.2
|
|
52
|
+
- click >= 8.3.1
|
|
53
|
+
- httpx >= 0.28.1
|
|
54
|
+
- fake-useragent >= 2.2.0
|
|
55
|
+
|
|
56
|
+
## 🚀 快速开始
|
|
57
|
+
|
|
58
|
+
### 启动服务端
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# 使用默认配置启动
|
|
62
|
+
ipclick run
|
|
63
|
+
|
|
64
|
+
# 指定端口和地址
|
|
65
|
+
ipclick run --host 0.0.0.0 --port 9527
|
|
66
|
+
|
|
67
|
+
# 使用自定义配置文件
|
|
68
|
+
ipclick run --config /path/to/config.yaml
|
|
69
|
+
|
|
70
|
+
# 显示详细日志
|
|
71
|
+
ipclick run --verbose
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 客户端使用
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from ipclick import Downloader, HttpMethod
|
|
78
|
+
|
|
79
|
+
# 创建下载器实例
|
|
80
|
+
downloader = Downloader()
|
|
81
|
+
|
|
82
|
+
# 发送 GET 请求
|
|
83
|
+
response = downloader.get("https://httpbin.org/ip")
|
|
84
|
+
print(response.text)
|
|
85
|
+
print(response.json())
|
|
86
|
+
|
|
87
|
+
# 发送带参数的请求
|
|
88
|
+
response = downloader.request(
|
|
89
|
+
method=HttpMethod.GET,
|
|
90
|
+
url="https://httpbin.org/get",
|
|
91
|
+
headers={"User-Agent": "IPClick/1.0"},
|
|
92
|
+
params={"key": "value"},
|
|
93
|
+
timeout=30
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# 检查请求是否成功
|
|
97
|
+
if response.is_success():
|
|
98
|
+
print(f"请求成功,耗时: {response.elapsed_ms}ms")
|
|
99
|
+
else:
|
|
100
|
+
print(f"请求失败: {response.error}")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 使用代理
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from ipclick import Downloader, ProxyConfig, HttpMethod
|
|
107
|
+
|
|
108
|
+
# 方式一:使用代理配置对象
|
|
109
|
+
proxy = ProxyConfig(
|
|
110
|
+
scheme="http",
|
|
111
|
+
host="proxy.example.com",
|
|
112
|
+
port=8080,
|
|
113
|
+
auth_key="username",
|
|
114
|
+
auth_password="password"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
response = downloader.request(
|
|
118
|
+
method=HttpMethod.GET,
|
|
119
|
+
url="https://httpbin.org/ip",
|
|
120
|
+
proxy=proxy
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# 方式二:使用代理 URL 字符串
|
|
124
|
+
response = downloader.request(
|
|
125
|
+
method=HttpMethod.GET,
|
|
126
|
+
url="https://httpbin.org/ip",
|
|
127
|
+
proxy="http://user:pass@proxy.example.com:8080"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# 方式三:使用配置文件中的代理(设置 proxy=True)
|
|
131
|
+
response = downloader.request(
|
|
132
|
+
method=HttpMethod.GET,
|
|
133
|
+
url="https://httpbin.org/ip",
|
|
134
|
+
proxy=True
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 使用全局下载器
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from ipclick import downloader
|
|
142
|
+
|
|
143
|
+
# 使用默认的全局下载器实例
|
|
144
|
+
response = downloader.get("https://httpbin.org/ip")
|
|
145
|
+
print(response.text)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 📂 项目结构
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
IPClick/
|
|
152
|
+
├── src/
|
|
153
|
+
│ └── ipclick/
|
|
154
|
+
│ ├── __init__.py # 包入口,导出公共 API
|
|
155
|
+
│ ├── __main__.py # 模块入口
|
|
156
|
+
│ ├── sdk. py # SDK 客户端实现
|
|
157
|
+
│ ├── server.py # gRPC 服务端实现
|
|
158
|
+
│ ├── adapters/ # HTTP 客户端适配器
|
|
159
|
+
│ │ ├── base.py # 适配器基类
|
|
160
|
+
│ │ ├── curl_cffi_adapter.py
|
|
161
|
+
│ │ └── httpx_adapter.py
|
|
162
|
+
│ ├── cli/ # 命令行工具
|
|
163
|
+
│ │ └── main.py
|
|
164
|
+
│ ├── config_loader/ # 配置加载器
|
|
165
|
+
│ ├── configs/ # 默认配置文件
|
|
166
|
+
│ ├── dto/ # 数据传输对象
|
|
167
|
+
│ │ ├── models.py # 数据模型定义
|
|
168
|
+
│ │ ├── response.py # 响应对象
|
|
169
|
+
│ │ └── proto/ # Protobuf 定义
|
|
170
|
+
│ ├── services/ # gRPC 服务实现
|
|
171
|
+
│ └── utils/ # 工具模块
|
|
172
|
+
├── docker/ # Docker 相关文件
|
|
173
|
+
│ └── Dockerfile
|
|
174
|
+
├── examples/ # 示例代码
|
|
175
|
+
├── tests/ # 测试代码
|
|
176
|
+
├── pyproject.toml # 项目配置
|
|
177
|
+
└── README. md
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## ⚙️ 配置说明
|
|
181
|
+
|
|
182
|
+
### 服务端配置
|
|
183
|
+
|
|
184
|
+
| 配置项 | 说明 | 默认值 |
|
|
185
|
+
|----------------------|---------|-----------|
|
|
186
|
+
| `SERVER. host` | 服务绑定地址 | `0.0.0.0` |
|
|
187
|
+
| `SERVER.port` | 服务端口 | `9527` |
|
|
188
|
+
| `SERVER.max_workers` | 最大工作线程数 | `10` |
|
|
189
|
+
|
|
190
|
+
### 客户端配置
|
|
191
|
+
|
|
192
|
+
| 配置项 | 说明 | 默认值 |
|
|
193
|
+
|----------------------------|-----------|--------|
|
|
194
|
+
| `DOWNLOADER.timeout` | 默认超时时间(秒) | `60` |
|
|
195
|
+
| `DOWNLOADER.max_retries` | 最大重试次数 | `3` |
|
|
196
|
+
| `DOWNLOADER.retry_backoff` | 重试退避时间(秒) | `2. 0` |
|
|
197
|
+
|
|
198
|
+
## 🐳 Docker 部署
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# 构建镜像
|
|
202
|
+
cd docker
|
|
203
|
+
docker build -t ipclick .
|
|
204
|
+
|
|
205
|
+
# 运行容器
|
|
206
|
+
docker run -d -p 9527:9527 --name ipclick ipclick
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 📚 API 参考
|
|
210
|
+
|
|
211
|
+
### DownloadTask 参数
|
|
212
|
+
|
|
213
|
+
| 参数 | 类型 | 说明 |
|
|
214
|
+
|-------------------|------------------------|------------|
|
|
215
|
+
| `url` | `str` | 请求 URL(必填) |
|
|
216
|
+
| `method` | `HttpMethod` | HTTP 方法 |
|
|
217
|
+
| `headers` | `Dict` | 请求头 |
|
|
218
|
+
| `cookies` | `Dict/str` | Cookies |
|
|
219
|
+
| `params` | `Dict` | URL 查询参数 |
|
|
220
|
+
| `data` | `Any` | 表单数据 |
|
|
221
|
+
| `json` | `Dict` | JSON 数据 |
|
|
222
|
+
| `proxy` | `ProxyConfig/str/bool` | 代理配置 |
|
|
223
|
+
| `timeout` | `float` | 超时时间(秒) |
|
|
224
|
+
| `max_retries` | `int` | 最大重试次数 |
|
|
225
|
+
| `verify` | `bool` | 是否验证 SSL |
|
|
226
|
+
| `allow_redirects` | `bool` | 是否跟随重定向 |
|
|
227
|
+
| `impersonate` | `str` | 浏览器指纹伪装 |
|
|
228
|
+
|
|
229
|
+
### DownloadResponse 属性
|
|
230
|
+
|
|
231
|
+
| 属性 | 类型 | 说明 |
|
|
232
|
+
|---------------|---------|-----------|
|
|
233
|
+
| `status_code` | `int` | HTTP 状态码 |
|
|
234
|
+
| `headers` | `Dict` | 响应头 |
|
|
235
|
+
| `content` | `bytes` | 响应内容(二进制) |
|
|
236
|
+
| `text` | `str` | 响应内容(文本) |
|
|
237
|
+
| `url` | `str` | 最终 URL |
|
|
238
|
+
| `elapsed_ms` | `int` | 请求耗时(毫秒) |
|
|
239
|
+
| `error` | `str` | 错误信息 |
|
|
240
|
+
|
|
241
|
+
### DownloadResponse 方法
|
|
242
|
+
|
|
243
|
+
- `json()` - 解析 JSON 响应
|
|
244
|
+
- `is_success()` - 判断请求是否成功
|
|
245
|
+
- `raise_for_status()` - 状态码异常时抛出异常
|
|
246
|
+
|
|
247
|
+
## 🤝 贡献
|
|
248
|
+
|
|
249
|
+
欢迎贡献代码、报告问题或提出建议!请通过 [GitHub Issues](https://github.com/yuanqimanong/IPClick/issues)
|
|
250
|
+
或 [Pull Requests](https://github.com/yuanqimanong/IPClick/pulls) 参与项目开发。
|
|
251
|
+
|
|
252
|
+
## 📄 许可证
|
|
253
|
+
|
|
254
|
+
本项目采用 [MIT License](LICENSE) 开源许可证。
|
|
255
|
+
|
|
256
|
+
Copyright (c) 2025 元气码农少女酱
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ipclick"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "IPClick Tool"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "元气码农少女酱", email = "1276162429@qq.com" }
|
|
7
|
+
]
|
|
8
|
+
license = { text = "MIT License" }
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.14"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"curl-cffi (>=0.13.0,<0.14.0)",
|
|
13
|
+
"grpcio (>=1.76.0,<2.0.0)",
|
|
14
|
+
"protobuf (>=6.33.2,<7.0.0)",
|
|
15
|
+
"click (>=8.3.1,<9.0.0)",
|
|
16
|
+
"httpx (>=0.28.1,<0.29.0)",
|
|
17
|
+
"fake-useragent (>=2.2.0,<3.0.0)",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
"Homepage" = "https://github.com/yuanqimanong/IPClick"
|
|
22
|
+
"Repository" = "https://github.com/yuanqimanong/IPClick"
|
|
23
|
+
"Bug Tracker" = "https://github.com/yuanqimanong/IPClick/issues"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
[build-system]
|
|
27
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
28
|
+
build-backend = "poetry.core.masonry.api"
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"grpcio-tools (>=1.76.0,<2.0.0)",
|
|
33
|
+
"requests (>=2.32.5,<3.0.0)",
|
|
34
|
+
"twine (>=6.2.0,<7.0.0)"
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
ipclick = "ipclick.__main__:main"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
@time: 2025-12-08
|
|
5
|
+
@author: Hades
|
|
6
|
+
@file: __init__.py
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from ipclick.config_loader import load_config
|
|
10
|
+
from ipclick.dto.models import DownloadTask, DownloadResponse, HttpMethod, Adapter, ProxyConfig
|
|
11
|
+
from ipclick.sdk import Downloader, downloader
|
|
12
|
+
|
|
13
|
+
__version__ = "1.0.0"
|
|
14
|
+
__author__ = "Hades"
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'Downloader',
|
|
18
|
+
'downloader',
|
|
19
|
+
'DownloadTask',
|
|
20
|
+
'DownloadResponse',
|
|
21
|
+
'HttpMethod',
|
|
22
|
+
'Adapter',
|
|
23
|
+
'ProxyConfig',
|
|
24
|
+
'load_config'
|
|
25
|
+
]
|