crawlo 1.4.6__py3-none-any.whl → 1.4.8__py3-none-any.whl

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.

Potentially problematic release.


This version of crawlo might be problematic. Click here for more details.

Files changed (162) hide show
  1. crawlo/__init__.py +2 -1
  2. crawlo/__version__.py +1 -1
  3. crawlo/cli.py +2 -2
  4. crawlo/commands/check.py +1 -1
  5. crawlo/commands/help.py +5 -3
  6. crawlo/commands/list.py +1 -1
  7. crawlo/commands/run.py +49 -11
  8. crawlo/commands/stats.py +1 -1
  9. crawlo/config.py +12 -4
  10. crawlo/config_validator.py +1 -1
  11. crawlo/core/engine.py +20 -7
  12. crawlo/core/processor.py +1 -1
  13. crawlo/core/scheduler.py +4 -5
  14. crawlo/crawler.py +51 -10
  15. crawlo/downloader/__init__.py +7 -3
  16. crawlo/downloader/aiohttp_downloader.py +18 -18
  17. crawlo/downloader/cffi_downloader.py +5 -2
  18. crawlo/downloader/httpx_downloader.py +9 -3
  19. crawlo/downloader/hybrid_downloader.py +2 -2
  20. crawlo/downloader/playwright_downloader.py +38 -15
  21. crawlo/downloader/selenium_downloader.py +16 -2
  22. crawlo/event.py +42 -8
  23. crawlo/exceptions.py +157 -24
  24. crawlo/extension/__init__.py +10 -9
  25. crawlo/extension/health_check.py +7 -7
  26. crawlo/extension/log_interval.py +6 -6
  27. crawlo/extension/log_stats.py +2 -2
  28. crawlo/extension/logging_extension.py +4 -12
  29. crawlo/extension/memory_monitor.py +5 -5
  30. crawlo/extension/performance_profiler.py +5 -5
  31. crawlo/extension/request_recorder.py +6 -6
  32. crawlo/factories/base.py +1 -1
  33. crawlo/factories/crawler.py +61 -60
  34. crawlo/factories/utils.py +135 -0
  35. crawlo/filters/__init__.py +19 -2
  36. crawlo/filters/aioredis_filter.py +133 -49
  37. crawlo/filters/memory_filter.py +6 -21
  38. crawlo/framework.py +22 -8
  39. crawlo/initialization/built_in.py +24 -67
  40. crawlo/initialization/core.py +65 -19
  41. crawlo/initialization/phases.py +83 -2
  42. crawlo/initialization/registry.py +5 -7
  43. crawlo/initialization/utils.py +49 -0
  44. crawlo/logging/__init__.py +6 -10
  45. crawlo/logging/config.py +106 -22
  46. crawlo/logging/factory.py +12 -8
  47. crawlo/logging/manager.py +19 -27
  48. crawlo/middleware/__init__.py +72 -9
  49. crawlo/middleware/default_header.py +2 -2
  50. crawlo/middleware/download_delay.py +2 -2
  51. crawlo/middleware/middleware_manager.py +6 -6
  52. crawlo/middleware/offsite.py +2 -2
  53. crawlo/middleware/proxy.py +2 -2
  54. crawlo/middleware/request_ignore.py +4 -4
  55. crawlo/middleware/response_code.py +2 -2
  56. crawlo/middleware/response_filter.py +2 -2
  57. crawlo/middleware/retry.py +1 -1
  58. crawlo/mode_manager.py +38 -4
  59. crawlo/network/request.py +54 -26
  60. crawlo/network/response.py +69 -135
  61. crawlo/pipelines/__init__.py +40 -9
  62. crawlo/pipelines/base_pipeline.py +452 -0
  63. crawlo/pipelines/bloom_dedup_pipeline.py +4 -5
  64. crawlo/pipelines/console_pipeline.py +2 -2
  65. crawlo/pipelines/csv_pipeline.py +4 -4
  66. crawlo/pipelines/database_dedup_pipeline.py +4 -5
  67. crawlo/pipelines/json_pipeline.py +4 -4
  68. crawlo/pipelines/memory_dedup_pipeline.py +4 -5
  69. crawlo/pipelines/mongo_pipeline.py +23 -14
  70. crawlo/pipelines/mysql_pipeline.py +31 -39
  71. crawlo/pipelines/pipeline_manager.py +8 -8
  72. crawlo/pipelines/redis_dedup_pipeline.py +13 -14
  73. crawlo/project.py +1 -1
  74. crawlo/queue/__init__.py +10 -0
  75. crawlo/queue/queue_manager.py +79 -13
  76. crawlo/queue/redis_priority_queue.py +196 -47
  77. crawlo/settings/default_settings.py +16 -6
  78. crawlo/spider/__init__.py +6 -5
  79. crawlo/stats_collector.py +2 -2
  80. crawlo/task_manager.py +1 -1
  81. crawlo/templates/crawlo.cfg.tmpl +3 -3
  82. crawlo/templates/project/__init__.py.tmpl +1 -3
  83. crawlo/templates/project/items.py.tmpl +2 -6
  84. crawlo/templates/project/middlewares.py.tmpl +1 -1
  85. crawlo/templates/project/pipelines.py.tmpl +1 -2
  86. crawlo/templates/project/settings.py.tmpl +12 -10
  87. crawlo/templates/project/settings_distributed.py.tmpl +14 -13
  88. crawlo/templates/project/settings_gentle.py.tmpl +21 -23
  89. crawlo/templates/project/settings_high_performance.py.tmpl +21 -23
  90. crawlo/templates/project/settings_minimal.py.tmpl +10 -8
  91. crawlo/templates/project/settings_simple.py.tmpl +21 -23
  92. crawlo/templates/run.py.tmpl +1 -1
  93. crawlo/templates/spider/spider.py.tmpl +4 -12
  94. crawlo/templates/spiders_init.py.tmpl +3 -8
  95. crawlo/tools/__init__.py +0 -103
  96. crawlo/tools/scenario_adapter.py +1 -1
  97. crawlo/utils/__init__.py +25 -1
  98. crawlo/utils/batch_processor.py +23 -6
  99. crawlo/utils/config_manager.py +442 -0
  100. crawlo/utils/controlled_spider_mixin.py +1 -1
  101. crawlo/utils/db_helper.py +1 -1
  102. crawlo/utils/encoding_helper.py +190 -0
  103. crawlo/utils/error_handler.py +2 -2
  104. crawlo/utils/large_scale_helper.py +1 -1
  105. crawlo/utils/leak_detector.py +335 -0
  106. crawlo/utils/mongo_connection_pool.py +157 -0
  107. crawlo/utils/mysql_connection_pool.py +197 -0
  108. crawlo/utils/performance_monitor.py +1 -1
  109. crawlo/utils/redis_checker.py +91 -0
  110. crawlo/utils/redis_connection_pool.py +260 -70
  111. crawlo/utils/redis_key_validator.py +1 -1
  112. crawlo/utils/request.py +24 -2
  113. crawlo/utils/request_serializer.py +1 -1
  114. crawlo/utils/resource_manager.py +337 -0
  115. crawlo/utils/response_helper.py +113 -0
  116. crawlo/utils/selector_helper.py +3 -2
  117. crawlo/utils/singleton.py +70 -0
  118. crawlo/utils/spider_loader.py +1 -1
  119. crawlo/utils/text_helper.py +1 -1
  120. crawlo-1.4.8.dist-info/METADATA +831 -0
  121. {crawlo-1.4.6.dist-info → crawlo-1.4.8.dist-info}/RECORD +131 -145
  122. tests/advanced_tools_example.py +10 -68
  123. tests/distributed_dedup_test.py +467 -0
  124. tests/monitor_redis_dedup.sh +72 -0
  125. tests/ofweek_scrapy/ofweek_scrapy/spiders/__init__.py +4 -4
  126. tests/simple_cli_test.py +55 -0
  127. tests/test_cli_arguments.py +119 -0
  128. tests/test_dedup_fix.py +10 -10
  129. crawlo/logging/async_handler.py +0 -181
  130. crawlo/logging/monitor.py +0 -153
  131. crawlo/logging/sampler.py +0 -167
  132. crawlo/tools/authenticated_proxy.py +0 -241
  133. crawlo/tools/data_formatter.py +0 -226
  134. crawlo/tools/data_validator.py +0 -181
  135. crawlo/tools/encoding_converter.py +0 -127
  136. crawlo/tools/network_diagnostic.py +0 -365
  137. crawlo/tools/request_tools.py +0 -83
  138. crawlo/tools/retry_mechanism.py +0 -224
  139. crawlo/utils/env_config.py +0 -143
  140. crawlo/utils/large_scale_config.py +0 -287
  141. crawlo/utils/log.py +0 -80
  142. crawlo/utils/system.py +0 -11
  143. crawlo/utils/tools.py +0 -5
  144. crawlo/utils/url.py +0 -40
  145. crawlo-1.4.6.dist-info/METADATA +0 -329
  146. tests/env_config_example.py +0 -134
  147. tests/ofweek_scrapy/ofweek_scrapy/spiders/ofweek_spider.py +0 -162
  148. tests/test_authenticated_proxy.py +0 -142
  149. tests/test_comprehensive.py +0 -147
  150. tests/test_dynamic_downloaders_proxy.py +0 -125
  151. tests/test_dynamic_proxy.py +0 -93
  152. tests/test_dynamic_proxy_config.py +0 -147
  153. tests/test_dynamic_proxy_real.py +0 -110
  154. tests/test_env_config.py +0 -122
  155. tests/test_framework_env_usage.py +0 -104
  156. tests/test_large_scale_config.py +0 -113
  157. tests/test_proxy_api.py +0 -265
  158. tests/test_real_scenario_proxy.py +0 -196
  159. tests/tools_example.py +0 -261
  160. {crawlo-1.4.6.dist-info → crawlo-1.4.8.dist-info}/WHEEL +0 -0
  161. {crawlo-1.4.6.dist-info → crawlo-1.4.8.dist-info}/entry_points.txt +0 -0
  162. {crawlo-1.4.6.dist-info → crawlo-1.4.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,831 @@
1
+ Metadata-Version: 2.4
2
+ Name: crawlo
3
+ Version: 1.4.8
4
+ Summary: Crawlo: A high-performance asynchronous Python web crawling framework with distributed support.。
5
+ Home-page: https://github.com/crawl-coder/Crawlo.git
6
+ Author: crawl-coder
7
+ Author-email: crawlo@qq.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: aiohttp>=3.12.14
15
+ Requires-Dist: aiomysql>=0.2.0
16
+ Requires-Dist: aioredis>=2.0.1
17
+ Requires-Dist: asyncmy>=0.2.10
18
+ Requires-Dist: cssselect>=1.2.0
19
+ Requires-Dist: dateparser>=1.2.2
20
+ Requires-Dist: httpx[http2]>=0.27.0
21
+ Requires-Dist: curl-cffi>=0.13.0
22
+ Requires-Dist: lxml>=5.2.1
23
+ Requires-Dist: motor>=3.7.0
24
+ Requires-Dist: parsel>=1.9.1
25
+ Requires-Dist: pydantic>=2.11.7
26
+ Requires-Dist: pymongo>=4.11
27
+ Requires-Dist: PyMySQL>=1.1.1
28
+ Requires-Dist: python-dateutil>=2.9.0.post0
29
+ Requires-Dist: redis>=6.2.0
30
+ Requires-Dist: requests>=2.32.4
31
+ Requires-Dist: six>=1.17.0
32
+ Requires-Dist: ujson>=5.9.0
33
+ Requires-Dist: urllib3>=2.5.0
34
+ Requires-Dist: w3lib>=2.1.2
35
+ Requires-Dist: rich>=14.1.0
36
+ Requires-Dist: astor>=0.8.1
37
+ Requires-Dist: watchdog>=6.0.0
38
+ Provides-Extra: render
39
+ Requires-Dist: webdriver-manager>=4.0.0; extra == "render"
40
+ Requires-Dist: playwright; extra == "render"
41
+ Requires-Dist: selenium>=3.141.0; extra == "render"
42
+ Provides-Extra: all
43
+ Requires-Dist: bitarray>=1.5.3; extra == "all"
44
+ Requires-Dist: PyExecJS>=1.5.1; extra == "all"
45
+ Requires-Dist: pymongo>=3.10.1; extra == "all"
46
+ Requires-Dist: redis-py-cluster>=2.1.0; extra == "all"
47
+ Requires-Dist: webdriver-manager>=4.0.0; extra == "all"
48
+ Requires-Dist: playwright; extra == "all"
49
+ Requires-Dist: selenium>=3.141.0; extra == "all"
50
+
51
+ <p align="center">
52
+ <img src="assets/logo.svg" alt="Crawlo Logo" width="150"/>
53
+ </p>
54
+
55
+ <h1 align="center">Crawlo</h1>
56
+
57
+ <p align="center">
58
+ <strong>一个基于 asyncio 的现代化、高性能 Python 异步爬虫框架。</strong>
59
+ </p>
60
+
61
+ <p align="center">
62
+ <a href="#核心特性">核心特性</a> •
63
+ <a href="#项目架构">架构</a> •
64
+ <a href="#安装">安装</a> •
65
+ <a href="#配置模式详解">配置模式</a> •
66
+ <a href="https://github.com/yourusername/crawlo">文档</a>
67
+ </p>
68
+
69
+ ## 核心特性
70
+
71
+ - 🚀 **高性能异步架构**:基于 asyncio 和 aiohttp,充分利用异步 I/O 提升爬取效率
72
+ - 🎯 **智能调度系统**:优先级队列、并发控制、自动重试、智能限速
73
+ - 🔄 **灵活的配置模式**:
74
+ - **Standalone 模式**:单机开发测试,使用内存队列
75
+ - **Distributed 模式**:多节点分布式部署,严格要求 Redis(不允许降级)
76
+ - **Auto 模式**:智能检测 Redis 可用性,自动选择最佳配置(推荐)
77
+ - 📦 **丰富的组件生态**:
78
+ - 内置 Redis 和 MongoDB 支持
79
+ - MySQL 异步连接池(基于 asyncmy和aiomysql分别实现)
80
+ - 多种过滤器和去重管道(Memory/Redis)
81
+ - 代理中间件支持(简单代理/动态代理)
82
+ - 多种下载器(aiohttp、httpx、curl-cffi)
83
+ - 🛠 **开发友好**:
84
+ - 类 Scrapy 的项目结构和 API 设计
85
+ - 配置工厂模式(`CrawloConfig.auto()`)
86
+ - 自动爬虫发现机制
87
+ - 完善的日志系统
88
+
89
+ ## 项目架构
90
+
91
+ Crawlo 框架采用模块化设计,核心组件包括:
92
+
93
+ ![Crawlo 框架架构图](images/Crawlo%20框架架构图.png)
94
+
95
+ - **Engine**:核心引擎,协调各个组件工作
96
+ - **Scheduler**:调度器,管理请求队列和去重
97
+ - **Downloader**:下载器,支持多种 HTTP 客户端
98
+ - **Spider**:爬虫基类,定义数据提取逻辑
99
+ - **Pipeline**:数据管道,处理和存储数据
100
+ - **Middleware**:中间件,处理请求和响应
101
+
102
+ ![Crawlo 数据流图](images/Crawlo%20数据流图.png)
103
+
104
+ ## 示例项目
105
+
106
+ 查看 [`examples/`](examples/) 目录下的完整示例项目:
107
+
108
+ - **ofweek_standalone** - Auto 模式示例(智能检测)
109
+ - **ofweek_spider** - Auto 模式示例
110
+ - **ofweek_distributed** - Distributed 模式示例(严格分布式)
111
+
112
+ ## 安装
113
+
114
+ ```bash
115
+ # 基础安装
116
+ pip install crawlo
117
+ ```
118
+
119
+ ## 配置模式详解
120
+
121
+ > ⚠️ **重要**:配置模式的选择直接影响爬虫的运行方式、性能和可靠性,请仔细阅读本节内容。
122
+
123
+ Crawlo 提供三种配置模式,满足不同场景需求:
124
+
125
+ ### 三种模式对比
126
+
127
+ | 配置项 | Standalone | Distributed | Auto |
128
+ |--------|-----------|-------------|------|
129
+ | **RUN_MODE** | `standalone` | `distributed` | `auto` |
130
+ | **队列类型** | 内存队列 | Redis 队列 | 自动检测 |
131
+ | **Redis 要求** | 不需要 | **必需** | 可选 |
132
+ | **Redis 不可用时** | N/A | 🚫 **报错退出** | ✅ 降级到内存 |
133
+ | **配置自动更新** | ❌ 否 | ❌ 否 | ✅ 是 |
134
+ | **过滤器** | Memory | Redis | Redis/Memory |
135
+ | **去重管道** | Memory | Redis | Redis/Memory |
136
+ | **适用场景** | 开发测试 | 多节点部署 | 生产环境 |
137
+ | **并发数默认值** | 8 | 16 | 12 |
138
+ | **推荐指数** | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
139
+
140
+ ### 1. Auto 模式(推荐)
141
+
142
+ **智能检测,自动适配,推荐用于生产环境。**
143
+
144
+ ```python
145
+ from crawlo.config import CrawloConfig
146
+
147
+ config = CrawloConfig.auto(
148
+ project_name='myproject',
149
+ concurrency=12,
150
+ download_delay=1.0
151
+ )
152
+ locals().update(config.to_dict())
153
+ ```
154
+
155
+ **运行机制**:
156
+ - 配置阶段不依赖 Redis
157
+ - 运行时才检测 Redis 可用性
158
+ - Redis 可用 → 使用 `RedisPriorityQueue` + `AioRedisFilter`
159
+ - Redis 不可用 → 降级到 `MemoryQueue` + `MemoryFilter`
160
+ - 自动更新配置(`QUEUE_TYPE`、`FILTER_CLASS`、`DEFAULT_DEDUP_PIPELINE`)
161
+
162
+ **优势**:
163
+ - ✅ 开发环境无需配置 Redis,直接启动
164
+ - ✅ 生产环境 Redis 故障时自动降级,保证系统可用性
165
+ - ✅ 同一份代码可在不同环境运行,无需修改配置
166
+ - ✅ 最佳的灵活性和可靠性
167
+
168
+ **适用场景**:
169
+ - 生产环境部署(首选)
170
+ - 需要在多种环境运行的项目
171
+ - 希望系统具备容错能力
172
+
173
+ ### 2. Standalone 模式
174
+
175
+ **单机模式,适合开发测试和中小规模爬取。**
176
+
177
+ ```python
178
+ config = CrawloConfig.standalone(
179
+ project_name='myproject',
180
+ concurrency=8
181
+ )
182
+ locals().update(config.to_dict())
183
+ ```
184
+
185
+ **运行机制**:
186
+ - 固定使用 `MemoryQueue`(内存队列)
187
+ - 固定使用 `MemoryFilter`(内存过滤器)
188
+ - 固定使用 `MemoryDedupPipeline`(内存去重)
189
+ - 不进行 Redis 检测
190
+ - 配置不会自动更新
191
+
192
+ **优势**:
193
+ - ✅ 无需任何外部依赖
194
+ - ✅ 启动速度快
195
+ - ✅ 适合快速开发调试
196
+
197
+ **限制**:
198
+ - ❌ 不支持分布式部署
199
+ - ❌ 重启后队列数据丢失
200
+ - ❌ 不适合大规模数据采集
201
+
202
+ **适用场景**:
203
+ - 本地开发调试
204
+ - 学习框架特性
205
+ - 中小规模数据采集(< 10万条)
206
+ - 单机运行的简单爬虫
207
+
208
+ ### 3. Distributed 模式
209
+
210
+ **分布式模式,严格要求 Redis 可用,适合多节点协同工作。**
211
+
212
+ ```python
213
+ config = CrawloConfig.distributed(
214
+ project_name='myproject',
215
+ redis_host='redis.example.com',
216
+ redis_port=6379,
217
+ redis_password='your_password',
218
+ concurrency=16
219
+ )
220
+ locals().update(config.to_dict())
221
+ ```
222
+
223
+ **运行机制**:
224
+ - 必须使用 `RedisPriorityQueue`
225
+ - 必须使用 `AioRedisFilter`
226
+ - 必须使用 `RedisDedupPipeline`
227
+ - 启动时强制检查 Redis 连接
228
+ - **Redis 不可用时抛出 `RuntimeError` 并退出(不允许降级)**
229
+
230
+ **为什么要严格要求 Redis?**
231
+
232
+ 1. **数据一致性**:防止不同节点使用不同的队列类型
233
+ 2. **去重有效性**:确保多节点间的去重功能正常工作
234
+ 3. **任务分配**:防止任务被重复执行
235
+ 4. **问题早发现**:启动失败比运行时失败更容易发现和修复
236
+ 5. **明确的意图**:分布式模式就应该是分布式的,不应该静默降级
237
+
238
+ **Redis 不可用时的错误信息**:
239
+
240
+ ```bash
241
+ $ crawlo run my_spider
242
+
243
+ 2025-10-25 22:00:00 - [queue_manager] - ERROR:
244
+ Distributed 模式要求 Redis 可用,但无法连接到 Redis 服务器。
245
+ 错误信息: Connection refused
246
+ Redis URL: redis://127.0.0.1:6379/0
247
+ 请检查:
248
+ 1. Redis 服务是否正在运行
249
+ 2. Redis 连接配置是否正确
250
+ 3. 网络连接是否正常
251
+
252
+ RuntimeError: Distributed 模式要求 Redis 可用,但无法连接到 Redis 服务器。
253
+ ```
254
+
255
+ **优势**:
256
+ - ✅ 支持多节点协同爬取
257
+ - ✅ 数据持久化,重启后可继续
258
+ - ✅ 严格的分布式一致性保证
259
+ - ✅ 适合大规模数据采集
260
+
261
+ **适用场景**:
262
+ - 多服务器协同采集
263
+ - 大规模数据采集(> 百万条)
264
+ - 需要严格保证分布式一致性
265
+ - 生产环境多节点部署
266
+
267
+ ### 模式选择建议
268
+
269
+ | 场景 | 推荐模式 | 原因 |
270
+ |------|---------|------|
271
+ | 生产环境(单节点或多节点) | **Auto** | 自动适配,容错能力强 |
272
+ | 开发环境 | **Standalone** 或 **Auto** | 无需配置 Redis |
273
+ | 严格的多节点分布式部署 | **Distributed** | 保证分布式一致性 |
274
+ | 学习和测试 | **Standalone** | 最简单,无依赖 |
275
+ | 中小规模爬取 | **Standalone** 或 **Auto** | 简单高效 |
276
+ | 大规模爬取 | **Auto** 或 **Distributed** | 性能和可靠性 |
277
+
278
+ > 📖 **完整文档**:更多详细信息请参考 [配置模式完全指南](docs/tutorials/configuration_modes.md)
279
+
280
+ ## 配置优先级
281
+
282
+ Crawlo 框架支持多层级的配置系统,了解配置优先级对于正确使用框架至关重要。
283
+
284
+ ### 配置来源与优先级
285
+
286
+ 从**低到高**的优先级顺序:
287
+
288
+ ```
289
+ 1. default_settings.py (框架默认配置) ⭐
290
+
291
+ 2. 环境变量 (CRAWLO_*) ⭐⭐
292
+ (在 default_settings.py 中通过 EnvConfigManager 读取)
293
+
294
+ 3. 用户 settings.py (项目配置文件) ⭐⭐⭐
295
+
296
+ 4. Spider.custom_settings (Spider 自定义配置) ⭐⭐⭐⭐
297
+
298
+ 5. 运行时 settings 参数 (crawl() 传入的配置) ⭐⭐⭐⭐⭐
299
+ ```
300
+
301
+ ### 环境变量配置
302
+
303
+ 所有环境变量都使用 `CRAWLO_` 前缀:
304
+
305
+ ```bash
306
+ # 基础配置
307
+ export CRAWLO_MODE=auto # 运行模式
308
+ export CRAWLO_PROJECT_NAME=myproject # 项目名称
309
+ export CRAWLO_CONCURRENCY=16 # 并发数
310
+
311
+ # Redis 配置
312
+ export CRAWLO_REDIS_HOST=127.0.0.1 # Redis 主机
313
+ export CRAWLO_REDIS_PORT=6379 # Redis 端口
314
+ export CRAWLO_REDIS_PASSWORD=your_password # Redis 密码
315
+ export CRAWLO_REDIS_DB=0 # Redis 数据库
316
+ ```
317
+
318
+ ### 配置合并策略
319
+
320
+ **普通配置**(如 `CONCURRENCY`):采用**覆盖策略**
321
+ ```python
322
+ # 假设各处都有定义
323
+ default_settings.py: 8 →
324
+ 环境变量: 12 →
325
+ settings.py: 16 →
326
+ Spider.custom_settings: 24 →
327
+ crawl(settings={...}): 32 ✅ 最终值 = 32
328
+ ```
329
+
330
+ **列表配置**(如 `MIDDLEWARES`、`PIPELINES`、`EXTENSIONS`):采用**合并策略**
331
+ ```python
332
+ # default_settings.py
333
+ PIPELINES = ['crawlo.pipelines.console_pipeline.ConsolePipeline']
334
+
335
+ # settings.py
336
+ PIPELINES = ['myproject.pipelines.MySQLPipeline']
337
+
338
+ # 最终结果(合并)
339
+ PIPELINES = [
340
+ 'crawlo.pipelines.console_pipeline.ConsolePipeline', # 保留默认
341
+ 'myproject.pipelines.MySQLPipeline', # 追加用户
342
+ ]
343
+ ```
344
+
345
+ ### Spider 级别配置
346
+
347
+ 在 Spider 类中可以覆盖项目配置:
348
+
349
+ ```python
350
+ class MySpider(Spider):
351
+ name = 'myspider'
352
+
353
+ custom_settings = {
354
+ 'CONCURRENCY': 32, # 覆盖项目配置
355
+ 'DOWNLOAD_DELAY': 2.0, # 覆盖项目配置
356
+ 'PIPELINES': [ # 会与默认管道合并
357
+ 'myproject.pipelines.SpecialPipeline',
358
+ ]
359
+ }
360
+ ```
361
+
362
+ ### 运行时动态配置
363
+
364
+ ```python
365
+ from crawlo import CrawlerProcess
366
+
367
+ process = CrawlerProcess()
368
+ await process.crawl(
369
+ MySpider,
370
+ settings={
371
+ 'CONCURRENCY': 64, # 最高优先级
372
+ 'DOWNLOAD_DELAY': 0.1,
373
+ }
374
+ )
375
+ ```
376
+
377
+ ### ⚠️ 常见陷阱
378
+
379
+ **陷阱1:环境变量被项目配置覆盖**
380
+ ```python
381
+ # 环境变量
382
+ export CRAWLO_REDIS_HOST=192.168.1.100
383
+
384
+ # settings.py(这会覆盖环境变量!)
385
+ REDIS_HOST = 'localhost' # ❌ 会覆盖环境变量
386
+
387
+ # 解决方案:不在 settings.py 中重复设置,或使用 CrawloConfig.auto()
388
+ ```
389
+
390
+ **陷阱2:误以为列表配置会被清空**
391
+ ```python
392
+ # settings.py
393
+ PIPELINES = ['myproject.pipelines.MySQLPipeline']
394
+
395
+ # 实际结果(默认管道会被保留并合并)
396
+ PIPELINES = [
397
+ 'crawlo.pipelines.console_pipeline.ConsolePipeline', # 默认保留
398
+ 'myproject.pipelines.MySQLPipeline', # 用户追加
399
+ ]
400
+
401
+ # 如果想完全替换,需要先清空
402
+ PIPELINES = [] # 清空
403
+ PIPELINES.append('myproject.pipelines.MySQLPipeline')
404
+ ```
405
+
406
+ > 📖 **详细文档**:完整的配置优先级说明请参考 [配置优先级详解](docs/配置优先级详解.md)
407
+
408
+ ## 快速开始
409
+
410
+ ### 1. 创建项目
411
+
412
+ ```bash
413
+ # 创建新项目
414
+ crawlo startproject myproject
415
+ cd myproject
416
+
417
+ # 创建爬虫
418
+ crawlo genspider example example.com
419
+ ```
420
+
421
+ ### 2. 配置项目(推荐使用 Auto 模式)
422
+
423
+ ```python
424
+ # myproject/settings.py
425
+ from crawlo.config import CrawloConfig
426
+
427
+ # 使用 Auto 模式:智能检测 Redis,自动选择最佳配置
428
+ config = CrawloConfig.auto(
429
+ project_name='myproject',
430
+ concurrency=12, # 并发数
431
+ download_delay=1.0 # 下载延迟(秒)
432
+ )
433
+
434
+ # 将配置应用到当前模块
435
+ locals().update(config.to_dict())
436
+
437
+ # 爬虫模块配置
438
+ SPIDER_MODULES = ['myproject.spiders']
439
+
440
+ # 日志配置
441
+ LOG_LEVEL = 'INFO'
442
+ LOG_FILE = 'logs/myproject.log'
443
+
444
+ # 可选:添加数据管道
445
+ # PIPELINES = [
446
+ # 'crawlo.pipelines.mysql_pipeline.AsyncmyMySQLPipeline',
447
+ # ]
448
+
449
+ # 可选:Redis 配置(Auto 模式会自动检测)
450
+ # REDIS_HOST = '127.0.0.1'
451
+ # REDIS_PORT = 6379
452
+ ```
453
+
454
+ **其他配置模式:**
455
+
456
+ ```python
457
+ # Standalone 模式:单机开发测试
458
+ config = CrawloConfig.standalone(
459
+ project_name='myproject',
460
+ concurrency=8
461
+ )
462
+
463
+ # Distributed 模式:多节点分布式(必须配置 Redis)
464
+ config = CrawloConfig.distributed(
465
+ project_name='myproject',
466
+ redis_host='redis.example.com',
467
+ redis_port=6379,
468
+ redis_password='your_password',
469
+ concurrency=16
470
+ )
471
+ ```
472
+
473
+ ### 3. 编写爬虫
474
+
475
+ ```python
476
+ # myproject/spiders/example.py
477
+ from crawlo import Spider
478
+ from crawlo.http import Request
479
+
480
+ class ExampleSpider(Spider):
481
+ name = 'example'
482
+ start_urls = ['https://example.com']
483
+
484
+ async def parse(self, response):
485
+ # 提取数据
486
+ title = response.css('h1::text').get()
487
+
488
+ # 返回数据
489
+ yield {
490
+ 'title': title,
491
+ 'url': response.url
492
+ }
493
+
494
+ # 跟进链接
495
+ for href in response.css('a::attr(href)').getall():
496
+ yield Request(
497
+ url=response.urljoin(href),
498
+ callback=self.parse
499
+ )
500
+ ```
501
+
502
+ ### 4. 运行爬虫
503
+
504
+ ```bash
505
+ # 运行指定爬虫
506
+ crawlo run example
507
+
508
+ # 指定日志级别
509
+ crawlo run example --log-level DEBUG
510
+ ```
511
+
512
+ ## 核心功能
513
+
514
+ ### Response 对象
515
+
516
+ Crawlo 的 [`Response`](crawlo/http/response.py) 对象提供了强大的网页处理能力:
517
+
518
+ **1. 智能编码检测**
519
+
520
+ ```python
521
+ # 自动检测并正确解码页面内容
522
+ # 优先级:Content-Type → HTML meta → chardet → utf-8
523
+ response.text # 已正确解码的文本
524
+ response.encoding # 检测到的编码
525
+ ```
526
+
527
+ **2. CSS/XPath 选择器**
528
+
529
+ ```python
530
+ # CSS 选择器(推荐)
531
+ title = response.css('h1::text').get()
532
+ links = response.css('a::attr(href)').getall()
533
+
534
+ # XPath 选择器
535
+ title = response.xpath('//title/text()').get()
536
+ links = response.xpath('//a/@href').getall()
537
+
538
+ # 支持默认值
539
+ title = response.css('h1::text').get(default='无标题')
540
+ ```
541
+
542
+ **3. URL 处理**
543
+
544
+ ```python
545
+ response.url # 自动规范化(移除 fragment)
546
+ response.original_url # 保留原始 URL
547
+
548
+ # 智能 URL 拼接
549
+ response.urljoin('/path') # 绝对路径
550
+ response.urljoin('../path') # 相对路径
551
+ response.urljoin('//cdn.com/img') # 协议相对路径
552
+ ```
553
+
554
+ **4. 便捷提取方法**
555
+
556
+ ```python
557
+ # 提取单个/多个元素文本
558
+ title = response.extract_text('h1')
559
+ paragraphs = response.extract_texts('.content p')
560
+
561
+ # 提取单个/多个元素属性
562
+ link = response.extract_attr('a', 'href')
563
+ all_links = response.extract_attrs('a', 'href')
564
+ ```
565
+
566
+ ### 配置工厂模式
567
+
568
+ Crawlo 提供了便捷的配置工厂方法,无需手动配置繁琐的参数:
569
+
570
+ ```python
571
+ from crawlo.config import CrawloConfig
572
+
573
+ # Auto 模式(推荐):智能检测,自动适配
574
+ config = CrawloConfig.auto(
575
+ project_name='myproject',
576
+ concurrency=12,
577
+ download_delay=1.0
578
+ )
579
+
580
+ # Standalone 模式:单机开发
581
+ config = CrawloConfig.standalone(
582
+ project_name='myproject',
583
+ concurrency=8
584
+ )
585
+
586
+ # Distributed 模式:严格分布式
587
+ config = CrawloConfig.distributed(
588
+ project_name='myproject',
589
+ redis_host='localhost',
590
+ redis_port=6379,
591
+ concurrency=16
592
+ )
593
+
594
+ # 应用到 settings.py
595
+ locals().update(config.to_dict())
596
+ ```
597
+
598
+ **三种模式的核心区别**:
599
+
600
+ - **Auto**:智能检测 Redis,自动选择最佳配置,**推荐用于生产环境**
601
+ - **Standalone**:固定使用内存队列,适合开发测试,无外部依赖
602
+ - **Distributed**:严格要求 Redis,不允许降级,保证分布式一致性
603
+
604
+ > 💡 详细配置说明请查看前面的 [配置模式详解](#配置模式详解) 章节
605
+
606
+ ### 日志系统
607
+
608
+ Crawlo 提供了完善的日志系统,支持控制台和文件双输出:
609
+
610
+ ```python
611
+ from crawlo.logging import get_logger
612
+
613
+ logger = get_logger(__name__)
614
+
615
+ logger.debug('调试信息')
616
+ logger.info('普通信息')
617
+ logger.warning('警告信息')
618
+ logger.error('错误信息')
619
+ ```
620
+
621
+ **日志配置:**
622
+
623
+ ```python
624
+ # settings.py
625
+ LOG_LEVEL = 'INFO' # DEBUG, INFO, WARNING, ERROR, CRITICAL
626
+ LOG_FILE = 'logs/spider.log'
627
+ LOG_ENCODING = 'utf-8' # 明确指定日志文件编码
628
+ STATS_DUMP = True # 是否输出统计信息
629
+ ```
630
+
631
+ **高级功能:**
632
+
633
+ ```python
634
+ from crawlo.logging import configure_logging
635
+
636
+ # 分别配置控制台和文件日志级别
637
+ configure_logging(
638
+ LOG_LEVEL='INFO',
639
+ LOG_CONSOLE_LEVEL='WARNING', # 控制台只显示 WARNING 及以上
640
+ LOG_FILE_LEVEL='DEBUG', # 文件记录 DEBUG 及以上
641
+ LOG_FILE='logs/app.log',
642
+ LOG_MAX_BYTES=10*1024*1024, # 10MB
643
+ LOG_BACKUP_COUNT=5
644
+ )
645
+ ```
646
+
647
+ ### 爬虫自动发现
648
+
649
+ Crawlo 支持自动发现爬虫,无需手动导入:
650
+
651
+ ```bash
652
+ # 自动发现并运行(推荐)
653
+ crawlo run spider_name
654
+
655
+ # 指定文件路径运行
656
+ crawlo run -f path/to/spider.py -s SpiderClassName
657
+ ```
658
+
659
+ 框架会自动在 `SPIDER_MODULES` 配置的模块中查找爬虫。
660
+
661
+ ### 跨平台支持
662
+
663
+ Crawlo 在 Windows、macOS、Linux 上均可无缝运行:
664
+
665
+ - **Windows**:自动使用 ProactorEventLoop,正确处理控制台编码
666
+ - **macOS/Linux**:使用默认的 SelectorEventLoop
667
+ - 兼容不同平台的路径格式
668
+
669
+ > 💡 **Windows 用户提示**:如需日志轮转功能,建议安装 `concurrent-log-handler`:
670
+ > ```bash
671
+ > pip install concurrent-log-handler
672
+ > ```
673
+
674
+ ![Crawlo 核心架构图](images/Crawlo%20核心架构图.png)
675
+
676
+ ## 文档
677
+
678
+ 完整文档请查看 [`docs/`](docs/) 目录:
679
+
680
+ ### 📚 核心教程
681
+
682
+ - [配置模式完全指南](docs/tutorials/configuration_modes.md) - **强烈推荐阅读**
683
+ - [架构概述](docs/modules/architecture/index.md)
684
+ - [运行模式](docs/modules/architecture/modes.md)
685
+ - [配置系统](docs/modules/configuration/index.md)
686
+
687
+ ### 🔧 核心模块
688
+
689
+ - [引擎 (Engine)](docs/modules/core/engine.md)
690
+ - [调度器 (Scheduler)](docs/modules/core/scheduler.md)
691
+ - [处理器 (Processor)](docs/modules/core/processor.md)
692
+ - [爬虫基类 (Spider)](docs/modules/core/spider.md)
693
+
694
+ ### 📦 功能模块
695
+
696
+ - [下载器 (Downloader)](docs/modules/downloader/index.md)
697
+ - [队列 (Queue)](docs/modules/queue/index.md)
698
+ - [过滤器 (Filter)](docs/modules/filter/index.md)
699
+ - [中间件 (Middleware)](docs/modules/middleware/index.md)
700
+ - [管道 (Pipeline)](docs/modules/pipeline/index.md)
701
+ - [扩展 (Extension)](docs/modules/extension/index.md)
702
+
703
+ ### 🛠 命令行工具
704
+
705
+ - [CLI 概述](docs/modules/cli/index.md)
706
+ - [startproject](docs/modules/cli/startproject.md) - 项目初始化
707
+ - [genspider](docs/modules/cli/genspider.md) - 爬虫生成
708
+ - [run](docs/modules/cli/run.md) - 爬虫运行
709
+ - [list](docs/modules/cli/list.md) - 查看爬虫列表
710
+ - [check](docs/modules/cli/check.md) - 配置检查
711
+ - [stats](docs/modules/cli/stats.md) - 统计信息
712
+
713
+ ### 🚀 高级主题
714
+
715
+ - [分布式部署](docs/modules/advanced/distributed.md)
716
+ - [性能优化](docs/modules/advanced/performance.md)
717
+ - [故障排除](docs/modules/advanced/troubleshooting.md)
718
+ - [最佳实践](docs/modules/advanced/best_practices.md)
719
+
720
+ ### 📝 性能优化报告
721
+
722
+ - [初始化优化报告](docs/initialization_optimization_report.md)
723
+ - [MySQL 连接池优化](docs/mysql_connection_pool_optimization.md)
724
+ - [MongoDB 连接池优化](docs/mongo_connection_pool_optimization.md)
725
+
726
+ ### 📖 API 参考
727
+
728
+ - [完整 API 文档](docs/api/)
729
+
730
+ ---
731
+
732
+ **在线文档**:
733
+ - [中文文档](https://crawlo.readthedocs.io/en/latest/README_zh/)
734
+ - [English Documentation](https://crawlo.readthedocs.io/en/latest/)
735
+
736
+ **本地构建文档**:
737
+ ```bash
738
+ mkdocs serve
739
+ # 浏览器访问 http://localhost:8000
740
+ ```
741
+
742
+ ## 常见问题
743
+
744
+ ### 1. 如何选择配置模式?
745
+
746
+ - **开发测试**:使用 `CrawloConfig.standalone()`
747
+ - **生产环境**:使用 `CrawloConfig.auto()`(推荐)
748
+ - **多节点部署**:使用 `CrawloConfig.distributed()`
749
+
750
+ ### 2. Distributed 模式 Redis 不可用怎么办?
751
+
752
+ Distributed 模式**严格要求 Redis**,不可用时会抛出 `RuntimeError` 并退出。这是为了保证分布式一致性和数据安全。
753
+
754
+ 如果希望 Redis 不可用时自动降级,请使用 **Auto 模式**。
755
+
756
+ ### 3. Auto 模式如何工作?
757
+
758
+ Auto 模式在运行时智能检测:
759
+ - Redis 可用 → 使用 RedisPriorityQueue + AioRedisFilter
760
+ - Redis 不可用 → 降级到 MemoryQueue + MemoryFilter
761
+
762
+ 详见 [配置模式完全指南](docs/tutorials/configuration_modes.md)。
763
+
764
+ ### 4. 如何启用 MySQL 或 MongoDB 支持?
765
+
766
+ ```python
767
+ # settings.py
768
+ PIPELINES = [
769
+ 'crawlo.pipelines.mysql_pipeline.AsyncmyMySQLPipeline', # MySQL
770
+ # 或
771
+ 'crawlo.pipelines.mongo_pipeline.MongoDBPipeline', # MongoDB
772
+ ]
773
+
774
+ # MySQL 配置
775
+ MYSQL_HOST = '127.0.0.1'
776
+ MYSQL_USER = 'root'
777
+ MYSQL_PASSWORD = 'password'
778
+ MYSQL_DB = 'mydb'
779
+ MYSQL_TABLE = 'items'
780
+
781
+ # MongoDB 配置
782
+ MONGO_URI = 'mongodb://localhost:27017'
783
+ MONGO_DATABASE = 'mydb'
784
+ MONGO_COLLECTION = 'items'
785
+ ```
786
+
787
+ ### 5. 如何使用代理?
788
+
789
+ ```python
790
+ # settings.py
791
+
792
+ # 简单代理列表
793
+ PROXY_LIST = [
794
+ "http://proxy1:8080",
795
+ "http://proxy2:8080"
796
+ ]
797
+
798
+ # 或使用动态代理 API
799
+ PROXY_API_URL = "http://your-proxy-api.com/get-proxy"
800
+ ```
801
+
802
+ ## 学习路径
803
+
804
+ 如果您是 Crawlo 的新用户,建议按以下顺序学习:
805
+
806
+ 1. **入门** - 阅读快速开始指南,运行第一个示例
807
+ 2. **配置模式** - 学习三种配置模式,选择适合的模式([配置模式指南](docs/tutorials/configuration_modes.md))
808
+ 3. **核心概念** - 了解框架架构和基本概念
809
+ 4. **核心模块** - 深入学习引擎、调度器、处理器等核嘿组件
810
+ 5. **功能模块** - 根据需求学习下载器、队列、过滤器等模块
811
+ 6. **高级主题** - 掌握分布式部署、性能优化等高级功能
812
+
813
+ ## 贡献
814
+
815
+ 欢迎贡献!如果您想为 Crawlo 做出贡献:
816
+
817
+ 1. Fork 项目仓库
818
+ 2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
819
+ 3. 提交您的更改 (`git commit -m 'Add some AmazingFeature'`)
820
+ 4. 推送到分支 (`git push origin feature/AmazingFeature`)
821
+ 5. 发起 Pull Request
822
+
823
+ ## 许可证
824
+
825
+ MIT License - 详见 [LICENSE](LICENSE) 文件
826
+
827
+ ---
828
+
829
+ <p align="center">
830
+ <i>如有问题或建议,欢迎提交 <a href="https://github.com/crawl-coder/Crawlo/issues">Issue</a></i>
831
+ </p>