crawlo 1.3.3__py3-none-any.whl → 1.3.4__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.
- crawlo/__init__.py +87 -63
- crawlo/__version__.py +1 -1
- crawlo/cli.py +75 -75
- crawlo/commands/__init__.py +14 -14
- crawlo/commands/check.py +594 -594
- crawlo/commands/genspider.py +151 -151
- crawlo/commands/help.py +138 -138
- crawlo/commands/list.py +155 -155
- crawlo/commands/run.py +341 -323
- crawlo/commands/startproject.py +436 -436
- crawlo/commands/stats.py +187 -187
- crawlo/commands/utils.py +196 -196
- crawlo/config.py +312 -312
- crawlo/config_validator.py +277 -277
- crawlo/core/__init__.py +46 -2
- crawlo/core/engine.py +439 -365
- crawlo/core/processor.py +40 -40
- crawlo/core/scheduler.py +257 -256
- crawlo/crawler.py +639 -1167
- crawlo/data/__init__.py +5 -5
- crawlo/data/user_agents.py +194 -194
- crawlo/downloader/__init__.py +273 -273
- crawlo/downloader/aiohttp_downloader.py +228 -226
- crawlo/downloader/cffi_downloader.py +245 -245
- crawlo/downloader/httpx_downloader.py +259 -259
- crawlo/downloader/hybrid_downloader.py +212 -212
- crawlo/downloader/playwright_downloader.py +402 -402
- crawlo/downloader/selenium_downloader.py +472 -472
- crawlo/event.py +11 -11
- crawlo/exceptions.py +81 -81
- crawlo/extension/__init__.py +39 -39
- crawlo/extension/health_check.py +141 -141
- crawlo/extension/log_interval.py +57 -57
- crawlo/extension/log_stats.py +81 -81
- crawlo/extension/logging_extension.py +61 -52
- crawlo/extension/memory_monitor.py +104 -104
- crawlo/extension/performance_profiler.py +133 -133
- crawlo/extension/request_recorder.py +107 -107
- crawlo/factories/__init__.py +28 -0
- crawlo/factories/base.py +69 -0
- crawlo/factories/crawler.py +104 -0
- crawlo/factories/registry.py +85 -0
- crawlo/filters/__init__.py +154 -154
- crawlo/filters/aioredis_filter.py +257 -234
- crawlo/filters/memory_filter.py +269 -269
- crawlo/framework.py +292 -0
- crawlo/initialization/__init__.py +40 -0
- crawlo/initialization/built_in.py +426 -0
- crawlo/initialization/context.py +142 -0
- crawlo/initialization/core.py +194 -0
- crawlo/initialization/phases.py +149 -0
- crawlo/initialization/registry.py +146 -0
- crawlo/items/__init__.py +23 -23
- crawlo/items/base.py +23 -22
- crawlo/items/fields.py +52 -52
- crawlo/items/items.py +104 -104
- crawlo/logging/__init__.py +38 -0
- crawlo/logging/config.py +97 -0
- crawlo/logging/factory.py +129 -0
- crawlo/logging/manager.py +112 -0
- crawlo/middleware/__init__.py +21 -21
- crawlo/middleware/default_header.py +132 -132
- crawlo/middleware/download_delay.py +104 -104
- crawlo/middleware/middleware_manager.py +135 -135
- crawlo/middleware/offsite.py +123 -123
- crawlo/middleware/proxy.py +386 -386
- crawlo/middleware/request_ignore.py +86 -86
- crawlo/middleware/response_code.py +163 -163
- crawlo/middleware/response_filter.py +136 -136
- crawlo/middleware/retry.py +124 -124
- crawlo/middleware/simple_proxy.py +65 -65
- crawlo/mode_manager.py +212 -187
- crawlo/network/__init__.py +21 -21
- crawlo/network/request.py +379 -379
- crawlo/network/response.py +359 -359
- crawlo/pipelines/__init__.py +21 -21
- crawlo/pipelines/bloom_dedup_pipeline.py +156 -156
- crawlo/pipelines/console_pipeline.py +39 -39
- crawlo/pipelines/csv_pipeline.py +316 -316
- crawlo/pipelines/database_dedup_pipeline.py +222 -222
- crawlo/pipelines/json_pipeline.py +218 -218
- crawlo/pipelines/memory_dedup_pipeline.py +115 -115
- crawlo/pipelines/mongo_pipeline.py +131 -131
- crawlo/pipelines/mysql_pipeline.py +318 -318
- crawlo/pipelines/pipeline_manager.py +76 -75
- crawlo/pipelines/redis_dedup_pipeline.py +166 -166
- crawlo/project.py +327 -325
- crawlo/queue/pqueue.py +43 -37
- crawlo/queue/queue_manager.py +503 -379
- crawlo/queue/redis_priority_queue.py +326 -306
- crawlo/settings/__init__.py +7 -7
- crawlo/settings/default_settings.py +321 -225
- crawlo/settings/setting_manager.py +214 -198
- crawlo/spider/__init__.py +657 -639
- crawlo/stats_collector.py +73 -59
- crawlo/subscriber.py +129 -129
- crawlo/task_manager.py +139 -30
- crawlo/templates/crawlo.cfg.tmpl +10 -10
- crawlo/templates/project/__init__.py.tmpl +3 -3
- crawlo/templates/project/items.py.tmpl +17 -17
- crawlo/templates/project/middlewares.py.tmpl +118 -118
- crawlo/templates/project/pipelines.py.tmpl +96 -96
- crawlo/templates/project/settings.py.tmpl +168 -267
- crawlo/templates/project/settings_distributed.py.tmpl +167 -180
- crawlo/templates/project/settings_gentle.py.tmpl +167 -61
- crawlo/templates/project/settings_high_performance.py.tmpl +168 -131
- crawlo/templates/project/settings_minimal.py.tmpl +66 -35
- crawlo/templates/project/settings_simple.py.tmpl +165 -102
- crawlo/templates/project/spiders/__init__.py.tmpl +10 -6
- crawlo/templates/run.py.tmpl +34 -38
- crawlo/templates/spider/spider.py.tmpl +143 -143
- crawlo/templates/spiders_init.py.tmpl +10 -0
- crawlo/tools/__init__.py +200 -200
- crawlo/tools/anti_crawler.py +268 -268
- crawlo/tools/authenticated_proxy.py +240 -240
- crawlo/tools/data_formatter.py +225 -225
- crawlo/tools/data_validator.py +180 -180
- crawlo/tools/date_tools.py +289 -289
- crawlo/tools/distributed_coordinator.py +388 -388
- crawlo/tools/encoding_converter.py +127 -127
- crawlo/tools/network_diagnostic.py +365 -0
- crawlo/tools/request_tools.py +82 -82
- crawlo/tools/retry_mechanism.py +224 -224
- crawlo/tools/scenario_adapter.py +262 -262
- crawlo/tools/text_cleaner.py +232 -232
- crawlo/utils/__init__.py +34 -34
- crawlo/utils/batch_processor.py +259 -259
- crawlo/utils/class_loader.py +26 -0
- crawlo/utils/controlled_spider_mixin.py +439 -439
- crawlo/utils/db_helper.py +343 -343
- crawlo/utils/enhanced_error_handler.py +356 -356
- crawlo/utils/env_config.py +142 -142
- crawlo/utils/error_handler.py +165 -124
- crawlo/utils/func_tools.py +82 -82
- crawlo/utils/large_scale_config.py +286 -286
- crawlo/utils/large_scale_helper.py +344 -344
- crawlo/utils/log.py +44 -200
- crawlo/utils/performance_monitor.py +285 -285
- crawlo/utils/queue_helper.py +175 -175
- crawlo/utils/redis_connection_pool.py +388 -351
- crawlo/utils/redis_key_validator.py +198 -198
- crawlo/utils/request.py +267 -267
- crawlo/utils/request_serializer.py +225 -218
- crawlo/utils/spider_loader.py +61 -61
- crawlo/utils/system.py +11 -11
- crawlo/utils/tools.py +4 -4
- crawlo/utils/url.py +39 -39
- {crawlo-1.3.3.dist-info → crawlo-1.3.4.dist-info}/METADATA +1126 -1020
- crawlo-1.3.4.dist-info/RECORD +278 -0
- examples/__init__.py +7 -7
- tests/__init__.py +7 -7
- tests/advanced_tools_example.py +275 -275
- tests/authenticated_proxy_example.py +107 -107
- tests/baidu_performance_test.py +109 -0
- tests/baidu_test.py +60 -0
- tests/cleaners_example.py +160 -160
- tests/comprehensive_framework_test.py +213 -0
- tests/comprehensive_test.py +82 -0
- tests/comprehensive_testing_summary.md +187 -0
- tests/config_validation_demo.py +142 -142
- tests/controlled_spider_example.py +205 -205
- tests/date_tools_example.py +180 -180
- tests/debug_configure.py +70 -0
- tests/debug_framework_logger.py +85 -0
- tests/debug_log_levels.py +64 -0
- tests/debug_pipelines.py +66 -66
- tests/distributed_test.py +67 -0
- tests/distributed_test_debug.py +77 -0
- tests/dynamic_loading_example.py +523 -523
- tests/dynamic_loading_test.py +104 -104
- tests/env_config_example.py +133 -133
- tests/error_handling_example.py +171 -171
- tests/final_command_test_report.md +0 -0
- tests/final_comprehensive_test.py +152 -0
- tests/final_validation_test.py +183 -0
- tests/framework_performance_test.py +203 -0
- tests/optimized_performance_test.py +212 -0
- tests/performance_comparison.py +246 -0
- tests/queue_blocking_test.py +114 -0
- tests/queue_test.py +90 -0
- tests/redis_key_validation_demo.py +130 -130
- tests/request_params_example.py +150 -150
- tests/response_improvements_example.py +144 -144
- tests/scrapy_comparison/ofweek_scrapy.py +139 -0
- tests/scrapy_comparison/scrapy_test.py +134 -0
- tests/simple_command_test.py +120 -0
- tests/simple_crawlo_test.py +128 -0
- tests/simple_log_test.py +58 -0
- tests/simple_optimization_test.py +129 -0
- tests/simple_spider_test.py +50 -0
- tests/simple_test.py +48 -0
- tests/test_advanced_tools.py +148 -148
- tests/test_all_commands.py +231 -0
- tests/test_all_redis_key_configs.py +145 -145
- tests/test_authenticated_proxy.py +141 -141
- tests/test_batch_processor.py +179 -0
- tests/test_cleaners.py +54 -54
- tests/test_component_factory.py +175 -0
- tests/test_comprehensive.py +146 -146
- tests/test_config_consistency.py +80 -80
- tests/test_config_merge.py +152 -152
- tests/test_config_validator.py +182 -182
- tests/test_controlled_spider_mixin.py +80 -0
- tests/test_crawlo_proxy_integration.py +108 -108
- tests/test_date_tools.py +123 -123
- tests/test_default_header_middleware.py +158 -158
- tests/test_distributed.py +65 -65
- tests/test_double_crawlo_fix.py +207 -207
- tests/test_double_crawlo_fix_simple.py +124 -124
- tests/test_download_delay_middleware.py +221 -221
- tests/test_downloader_proxy_compatibility.py +268 -268
- tests/test_dynamic_downloaders_proxy.py +124 -124
- tests/test_dynamic_proxy.py +92 -92
- tests/test_dynamic_proxy_config.py +146 -146
- tests/test_dynamic_proxy_real.py +109 -109
- tests/test_edge_cases.py +303 -303
- tests/test_enhanced_error_handler.py +270 -270
- tests/test_enhanced_error_handler_comprehensive.py +246 -0
- tests/test_env_config.py +121 -121
- tests/test_error_handler_compatibility.py +112 -112
- tests/test_factories.py +253 -0
- tests/test_final_validation.py +153 -153
- tests/test_framework_env_usage.py +103 -103
- tests/test_framework_logger.py +67 -0
- tests/test_framework_startup.py +65 -0
- tests/test_integration.py +169 -169
- tests/test_item_dedup_redis_key.py +122 -122
- tests/test_large_scale_config.py +113 -0
- tests/test_large_scale_helper.py +236 -0
- tests/test_mode_change.py +73 -0
- tests/test_mode_consistency.py +51 -51
- tests/test_offsite_middleware.py +221 -221
- tests/test_parsel.py +29 -29
- tests/test_performance.py +327 -327
- tests/test_performance_monitor.py +116 -0
- tests/test_proxy_api.py +264 -264
- tests/test_proxy_health_check.py +32 -32
- tests/test_proxy_middleware.py +121 -121
- tests/test_proxy_middleware_enhanced.py +216 -216
- tests/test_proxy_middleware_integration.py +136 -136
- tests/test_proxy_middleware_refactored.py +184 -184
- tests/test_proxy_providers.py +56 -56
- tests/test_proxy_stats.py +19 -19
- tests/test_proxy_strategies.py +59 -59
- tests/test_queue_empty_check.py +42 -0
- tests/test_queue_manager_double_crawlo.py +173 -173
- tests/test_queue_manager_redis_key.py +176 -176
- tests/test_random_user_agent.py +72 -72
- tests/test_real_scenario_proxy.py +195 -195
- tests/test_redis_config.py +28 -28
- tests/test_redis_connection_pool.py +294 -294
- tests/test_redis_key_naming.py +181 -181
- tests/test_redis_key_validator.py +123 -123
- tests/test_redis_queue.py +224 -224
- tests/test_request_ignore_middleware.py +182 -182
- tests/test_request_params.py +111 -111
- tests/test_request_serialization.py +70 -70
- tests/test_response_code_middleware.py +349 -349
- tests/test_response_filter_middleware.py +427 -427
- tests/test_response_improvements.py +152 -152
- tests/test_retry_middleware.py +241 -241
- tests/test_scheduler.py +252 -252
- tests/test_scheduler_config_update.py +133 -133
- tests/test_simple_response.py +61 -61
- tests/test_telecom_spider_redis_key.py +205 -205
- tests/test_template_content.py +87 -87
- tests/test_template_redis_key.py +134 -134
- tests/test_tools.py +159 -159
- tests/test_user_agents.py +96 -96
- tests/tools_example.py +260 -260
- tests/untested_features_report.md +139 -0
- tests/verify_debug.py +52 -0
- tests/verify_distributed.py +117 -117
- tests/verify_log_fix.py +112 -0
- crawlo-1.3.3.dist-info/RECORD +0 -219
- tests/DOUBLE_CRAWLO_PREFIX_FIX_REPORT.md +0 -82
- {crawlo-1.3.3.dist-info → crawlo-1.3.4.dist-info}/WHEEL +0 -0
- {crawlo-1.3.3.dist-info → crawlo-1.3.4.dist-info}/entry_points.txt +0 -0
- {crawlo-1.3.3.dist-info → crawlo-1.3.4.dist-info}/top_level.txt +0 -0
crawlo/__init__.py
CHANGED
|
@@ -1,64 +1,88 @@
|
|
|
1
|
-
#!/usr/bin/python
|
|
2
|
-
# -*- coding: UTF-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
Crawlo - 一个异步爬虫框架
|
|
5
|
-
"""
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
from crawlo.
|
|
9
|
-
from crawlo.
|
|
10
|
-
from crawlo.
|
|
11
|
-
from crawlo.
|
|
12
|
-
from crawlo.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Crawlo - 一个异步爬虫框架
|
|
5
|
+
"""
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from crawlo.spider import Spider
|
|
9
|
+
from crawlo.items import Item, Field
|
|
10
|
+
from crawlo.network.request import Request
|
|
11
|
+
from crawlo.network.response import Response
|
|
12
|
+
from crawlo.downloader import DownloaderBase
|
|
13
|
+
from crawlo.middleware import BaseMiddleware
|
|
14
|
+
from crawlo.utils import (
|
|
15
|
+
TimeUtils,
|
|
16
|
+
parse_time,
|
|
17
|
+
format_time,
|
|
18
|
+
time_diff,
|
|
19
|
+
to_timestamp,
|
|
20
|
+
to_datetime,
|
|
21
|
+
now,
|
|
22
|
+
to_timezone,
|
|
23
|
+
to_utc,
|
|
24
|
+
to_local,
|
|
25
|
+
from_timestamp_with_tz
|
|
26
|
+
)
|
|
27
|
+
from crawlo import tools
|
|
28
|
+
|
|
29
|
+
# 框架核心模块 - 使用TYPE_CHECKING避免循环导入
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from crawlo.core.framework_initializer import get_framework_initializer, initialize_framework
|
|
32
|
+
|
|
33
|
+
# 为了向后兼容,从tools中导入cleaners相关的功能
|
|
34
|
+
import crawlo.tools as cleaners
|
|
35
|
+
|
|
36
|
+
# 延迟导入的辅助函数
|
|
37
|
+
def get_framework_initializer():
|
|
38
|
+
"""延迟导入get_framework_initializer以避免循环依赖"""
|
|
39
|
+
from crawlo.core.framework_initializer import get_framework_initializer as _get_framework_initializer
|
|
40
|
+
return _get_framework_initializer()
|
|
41
|
+
|
|
42
|
+
def initialize_framework(custom_settings=None):
|
|
43
|
+
"""延迟导入initialize_framework以避免循环依赖"""
|
|
44
|
+
from crawlo.core.framework_initializer import initialize_framework as _initialize_framework
|
|
45
|
+
return _initialize_framework(custom_settings)
|
|
46
|
+
|
|
47
|
+
# 向后兼容的别名
|
|
48
|
+
def get_bootstrap_manager():
|
|
49
|
+
"""向后兼容的别名"""
|
|
50
|
+
return get_framework_initializer()
|
|
51
|
+
|
|
52
|
+
# 版本号:优先从元数据读取
|
|
53
|
+
try:
|
|
54
|
+
from importlib.metadata import version
|
|
55
|
+
__version__ = version("crawlo")
|
|
56
|
+
except Exception:
|
|
57
|
+
# 开发模式下可能未安装,回退到 __version__.py 或 dev
|
|
58
|
+
try:
|
|
59
|
+
from crawlo.__version__ import __version__
|
|
60
|
+
except ImportError:
|
|
61
|
+
__version__ = "dev"
|
|
62
|
+
|
|
63
|
+
# 定义对外 API
|
|
64
|
+
__all__ = [
|
|
65
|
+
'Spider',
|
|
66
|
+
'Item',
|
|
67
|
+
'Field',
|
|
68
|
+
'Request',
|
|
69
|
+
'Response',
|
|
70
|
+
'DownloaderBase',
|
|
71
|
+
'BaseMiddleware',
|
|
72
|
+
'TimeUtils',
|
|
73
|
+
'parse_time',
|
|
74
|
+
'format_time',
|
|
75
|
+
'time_diff',
|
|
76
|
+
'to_timestamp',
|
|
77
|
+
'to_datetime',
|
|
78
|
+
'now',
|
|
79
|
+
'to_timezone',
|
|
80
|
+
'to_utc',
|
|
81
|
+
'to_local',
|
|
82
|
+
'from_timestamp_with_tz',
|
|
83
|
+
'cleaners',
|
|
84
|
+
'tools',
|
|
85
|
+
'get_framework_initializer',
|
|
86
|
+
'get_bootstrap_manager',
|
|
87
|
+
'__version__',
|
|
64
88
|
]
|
crawlo/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '1.3.
|
|
1
|
+
__version__ = '1.3.4'
|
crawlo/cli.py
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
# crawlo/cli.py
|
|
2
|
-
# !/usr/bin/python
|
|
3
|
-
# -*- coding: UTF-8 -*-
|
|
4
|
-
import sys
|
|
5
|
-
import argparse
|
|
6
|
-
from crawlo.commands import get_commands
|
|
7
|
-
from crawlo.utils.env_config import get_version
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def main():
|
|
11
|
-
# 获取框架版本号
|
|
12
|
-
VERSION = get_version()
|
|
13
|
-
|
|
14
|
-
# 获取所有可用命令
|
|
15
|
-
commands = get_commands()
|
|
16
|
-
|
|
17
|
-
# 创建主解析器
|
|
18
|
-
parser = argparse.ArgumentParser(
|
|
19
|
-
description="Crawlo: A lightweight web crawler framework.",
|
|
20
|
-
usage="crawlo <command> [options]",
|
|
21
|
-
add_help=False # 禁用默认帮助,我们自己处理
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
# 添加帮助参数
|
|
25
|
-
parser.add_argument('-h', '--help', action='store_true', help='显示帮助信息')
|
|
26
|
-
parser.add_argument('-v', '--version', action='store_true', help='显示版本信息')
|
|
27
|
-
parser.add_argument('command', nargs='?', help='可用命令: ' + ', '.join(commands.keys()))
|
|
28
|
-
|
|
29
|
-
# 解析已知参数
|
|
30
|
-
args, unknown = parser.parse_known_args()
|
|
31
|
-
|
|
32
|
-
# 处理版本参数
|
|
33
|
-
if args.version:
|
|
34
|
-
print(f"Crawlo {VERSION}")
|
|
35
|
-
sys.exit(0)
|
|
36
|
-
|
|
37
|
-
# 处理帮助参数
|
|
38
|
-
if args.help or (args.command is None and not unknown):
|
|
39
|
-
# 导入并运行帮助命令
|
|
40
|
-
try:
|
|
41
|
-
module = __import__(commands['help'], fromlist=['main'])
|
|
42
|
-
sys.exit(module.main([]))
|
|
43
|
-
except ImportError as e:
|
|
44
|
-
print(f"Failed to load help command: {e}")
|
|
45
|
-
sys.exit(1)
|
|
46
|
-
except Exception as e:
|
|
47
|
-
print(f"Help command failed: {e}")
|
|
48
|
-
sys.exit(1)
|
|
49
|
-
|
|
50
|
-
# 检查命令是否存在
|
|
51
|
-
if args.command not in commands:
|
|
52
|
-
print(f"Unknown command: {args.command}")
|
|
53
|
-
print(f"Available commands: {', '.join(commands.keys())}")
|
|
54
|
-
# 显示帮助信息
|
|
55
|
-
try:
|
|
56
|
-
module = __import__(commands['help'], fromlist=['main'])
|
|
57
|
-
module.main([])
|
|
58
|
-
except:
|
|
59
|
-
pass
|
|
60
|
-
sys.exit(1)
|
|
61
|
-
|
|
62
|
-
# 动态导入并执行命令
|
|
63
|
-
try:
|
|
64
|
-
module = __import__(commands[args.command], fromlist=['main'])
|
|
65
|
-
# 将未知参数传递给子命令
|
|
66
|
-
sys.exit(module.main(unknown))
|
|
67
|
-
except ImportError as e:
|
|
68
|
-
print(f"Failed to load command '{args.command}': {e}")
|
|
69
|
-
sys.exit(1)
|
|
70
|
-
except Exception as e:
|
|
71
|
-
print(f"Command '{args.command}' failed: {e}")
|
|
72
|
-
sys.exit(1)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if __name__ == '__main__':
|
|
1
|
+
# crawlo/cli.py
|
|
2
|
+
# !/usr/bin/python
|
|
3
|
+
# -*- coding: UTF-8 -*-
|
|
4
|
+
import sys
|
|
5
|
+
import argparse
|
|
6
|
+
from crawlo.commands import get_commands
|
|
7
|
+
from crawlo.utils.env_config import get_version
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
# 获取框架版本号
|
|
12
|
+
VERSION = get_version()
|
|
13
|
+
|
|
14
|
+
# 获取所有可用命令
|
|
15
|
+
commands = get_commands()
|
|
16
|
+
|
|
17
|
+
# 创建主解析器
|
|
18
|
+
parser = argparse.ArgumentParser(
|
|
19
|
+
description="Crawlo: A lightweight web crawler framework.",
|
|
20
|
+
usage="crawlo <command> [options]",
|
|
21
|
+
add_help=False # 禁用默认帮助,我们自己处理
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# 添加帮助参数
|
|
25
|
+
parser.add_argument('-h', '--help', action='store_true', help='显示帮助信息')
|
|
26
|
+
parser.add_argument('-v', '--version', action='store_true', help='显示版本信息')
|
|
27
|
+
parser.add_argument('command', nargs='?', help='可用命令: ' + ', '.join(commands.keys()))
|
|
28
|
+
|
|
29
|
+
# 解析已知参数
|
|
30
|
+
args, unknown = parser.parse_known_args()
|
|
31
|
+
|
|
32
|
+
# 处理版本参数
|
|
33
|
+
if args.version:
|
|
34
|
+
print(f"Crawlo {VERSION}")
|
|
35
|
+
sys.exit(0)
|
|
36
|
+
|
|
37
|
+
# 处理帮助参数
|
|
38
|
+
if args.help or (args.command is None and not unknown):
|
|
39
|
+
# 导入并运行帮助命令
|
|
40
|
+
try:
|
|
41
|
+
module = __import__(commands['help'], fromlist=['main'])
|
|
42
|
+
sys.exit(module.main([]))
|
|
43
|
+
except ImportError as e:
|
|
44
|
+
print(f"Failed to load help command: {e}")
|
|
45
|
+
sys.exit(1)
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print(f"Help command failed: {e}")
|
|
48
|
+
sys.exit(1)
|
|
49
|
+
|
|
50
|
+
# 检查命令是否存在
|
|
51
|
+
if args.command not in commands:
|
|
52
|
+
print(f"Unknown command: {args.command}")
|
|
53
|
+
print(f"Available commands: {', '.join(commands.keys())}")
|
|
54
|
+
# 显示帮助信息
|
|
55
|
+
try:
|
|
56
|
+
module = __import__(commands['help'], fromlist=['main'])
|
|
57
|
+
module.main([])
|
|
58
|
+
except:
|
|
59
|
+
pass
|
|
60
|
+
sys.exit(1)
|
|
61
|
+
|
|
62
|
+
# 动态导入并执行命令
|
|
63
|
+
try:
|
|
64
|
+
module = __import__(commands[args.command], fromlist=['main'])
|
|
65
|
+
# 将未知参数传递给子命令
|
|
66
|
+
sys.exit(module.main(unknown))
|
|
67
|
+
except ImportError as e:
|
|
68
|
+
print(f"Failed to load command '{args.command}': {e}")
|
|
69
|
+
sys.exit(1)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
print(f"Command '{args.command}' failed: {e}")
|
|
72
|
+
sys.exit(1)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == '__main__':
|
|
76
76
|
main()
|
crawlo/commands/__init__.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
#!/usr/bin/python
|
|
2
|
-
# -*- coding:UTF-8 -*-
|
|
3
|
-
|
|
4
|
-
_commands = {
|
|
5
|
-
'startproject': 'crawlo.commands.startproject',
|
|
6
|
-
'genspider': 'crawlo.commands.genspider',
|
|
7
|
-
'run': 'crawlo.commands.run',
|
|
8
|
-
'check': 'crawlo.commands.check',
|
|
9
|
-
'list': 'crawlo.commands.list',
|
|
10
|
-
'stats': 'crawlo.commands.stats',
|
|
11
|
-
'help': 'crawlo.commands.help'
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
def get_commands():
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding:UTF-8 -*-
|
|
3
|
+
|
|
4
|
+
_commands = {
|
|
5
|
+
'startproject': 'crawlo.commands.startproject',
|
|
6
|
+
'genspider': 'crawlo.commands.genspider',
|
|
7
|
+
'run': 'crawlo.commands.run',
|
|
8
|
+
'check': 'crawlo.commands.check',
|
|
9
|
+
'list': 'crawlo.commands.list',
|
|
10
|
+
'stats': 'crawlo.commands.stats',
|
|
11
|
+
'help': 'crawlo.commands.help'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
def get_commands():
|
|
15
15
|
return _commands
|