crawlo 1.1.0__py3-none-any.whl → 1.1.1__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 (111) hide show
  1. crawlo/__init__.py +33 -24
  2. crawlo/__version__.py +1 -1
  3. crawlo/cli.py +40 -40
  4. crawlo/commands/__init__.py +13 -13
  5. crawlo/commands/check.py +594 -155
  6. crawlo/commands/genspider.py +125 -110
  7. crawlo/commands/list.py +147 -119
  8. crawlo/commands/run.py +285 -170
  9. crawlo/commands/startproject.py +111 -101
  10. crawlo/commands/stats.py +188 -167
  11. crawlo/core/__init__.py +2 -2
  12. crawlo/core/engine.py +158 -158
  13. crawlo/core/processor.py +40 -40
  14. crawlo/core/scheduler.py +57 -57
  15. crawlo/crawler.py +494 -492
  16. crawlo/downloader/__init__.py +78 -78
  17. crawlo/downloader/aiohttp_downloader.py +199 -199
  18. crawlo/downloader/cffi_downloader.py +242 -277
  19. crawlo/downloader/httpx_downloader.py +246 -246
  20. crawlo/event.py +11 -11
  21. crawlo/exceptions.py +78 -78
  22. crawlo/extension/__init__.py +31 -31
  23. crawlo/extension/log_interval.py +49 -49
  24. crawlo/extension/log_stats.py +44 -44
  25. crawlo/extension/logging_extension.py +34 -34
  26. crawlo/filters/__init__.py +37 -37
  27. crawlo/filters/aioredis_filter.py +150 -150
  28. crawlo/filters/memory_filter.py +202 -202
  29. crawlo/items/__init__.py +23 -23
  30. crawlo/items/base.py +21 -21
  31. crawlo/items/fields.py +53 -53
  32. crawlo/items/items.py +104 -104
  33. crawlo/middleware/__init__.py +21 -21
  34. crawlo/middleware/default_header.py +32 -32
  35. crawlo/middleware/download_delay.py +28 -28
  36. crawlo/middleware/middleware_manager.py +135 -135
  37. crawlo/middleware/proxy.py +245 -245
  38. crawlo/middleware/request_ignore.py +30 -30
  39. crawlo/middleware/response_code.py +18 -18
  40. crawlo/middleware/response_filter.py +26 -26
  41. crawlo/middleware/retry.py +90 -90
  42. crawlo/network/__init__.py +7 -7
  43. crawlo/network/request.py +203 -203
  44. crawlo/network/response.py +166 -166
  45. crawlo/pipelines/__init__.py +13 -13
  46. crawlo/pipelines/console_pipeline.py +39 -39
  47. crawlo/pipelines/mongo_pipeline.py +116 -116
  48. crawlo/pipelines/mysql_batch_pipline.py +272 -272
  49. crawlo/pipelines/mysql_pipeline.py +195 -195
  50. crawlo/pipelines/pipeline_manager.py +56 -56
  51. crawlo/project.py +153 -0
  52. crawlo/settings/__init__.py +7 -7
  53. crawlo/settings/default_settings.py +166 -168
  54. crawlo/settings/setting_manager.py +99 -99
  55. crawlo/spider/__init__.py +129 -129
  56. crawlo/stats_collector.py +59 -59
  57. crawlo/subscriber.py +106 -106
  58. crawlo/task_manager.py +27 -27
  59. crawlo/templates/crawlo.cfg.tmpl +10 -10
  60. crawlo/templates/project/__init__.py.tmpl +3 -3
  61. crawlo/templates/project/items.py.tmpl +17 -17
  62. crawlo/templates/project/middlewares.py.tmpl +75 -75
  63. crawlo/templates/project/pipelines.py.tmpl +63 -63
  64. crawlo/templates/project/settings.py.tmpl +54 -54
  65. crawlo/templates/project/spiders/__init__.py.tmpl +5 -5
  66. crawlo/templates/spider/spider.py.tmpl +31 -31
  67. crawlo/utils/__init__.py +7 -7
  68. crawlo/utils/date_tools.py +233 -233
  69. crawlo/utils/db_helper.py +343 -343
  70. crawlo/utils/func_tools.py +82 -82
  71. crawlo/utils/log.py +128 -128
  72. crawlo/utils/pqueue.py +173 -173
  73. crawlo/utils/request.py +267 -267
  74. crawlo/utils/spider_loader.py +62 -62
  75. crawlo/utils/system.py +11 -11
  76. crawlo/utils/tools.py +4 -4
  77. crawlo/utils/url.py +39 -39
  78. crawlo-1.1.1.dist-info/METADATA +220 -0
  79. crawlo-1.1.1.dist-info/RECORD +100 -0
  80. examples/__init__.py +7 -0
  81. examples/baidu_spider/__init__.py +7 -0
  82. examples/baidu_spider/demo.py +94 -0
  83. examples/baidu_spider/items.py +46 -0
  84. examples/baidu_spider/middleware.py +49 -0
  85. examples/baidu_spider/pipeline.py +55 -0
  86. examples/baidu_spider/run.py +27 -0
  87. examples/baidu_spider/settings.py +121 -0
  88. examples/baidu_spider/spiders/__init__.py +7 -0
  89. examples/baidu_spider/spiders/bai_du.py +61 -0
  90. examples/baidu_spider/spiders/miit.py +159 -0
  91. examples/baidu_spider/spiders/sina.py +79 -0
  92. tests/__init__.py +7 -7
  93. tests/test_proxy_health_check.py +32 -32
  94. tests/test_proxy_middleware_integration.py +136 -136
  95. tests/test_proxy_providers.py +56 -56
  96. tests/test_proxy_stats.py +19 -19
  97. tests/test_proxy_strategies.py +59 -59
  98. crawlo/utils/concurrency_manager.py +0 -125
  99. crawlo/utils/project.py +0 -197
  100. crawlo-1.1.0.dist-info/METADATA +0 -49
  101. crawlo-1.1.0.dist-info/RECORD +0 -97
  102. examples/gxb/__init__.py +0 -0
  103. examples/gxb/items.py +0 -36
  104. examples/gxb/run.py +0 -16
  105. examples/gxb/settings.py +0 -72
  106. examples/gxb/spider/__init__.py +0 -2
  107. examples/gxb/spider/miit_spider.py +0 -180
  108. examples/gxb/spider/telecom_device.py +0 -129
  109. {crawlo-1.1.0.dist-info → crawlo-1.1.1.dist-info}/WHEEL +0 -0
  110. {crawlo-1.1.0.dist-info → crawlo-1.1.1.dist-info}/entry_points.txt +0 -0
  111. {crawlo-1.1.0.dist-info → crawlo-1.1.1.dist-info}/top_level.txt +0 -0
crawlo/utils/system.py CHANGED
@@ -1,11 +1,11 @@
1
- #!/usr/bin/python
2
- # -*- coding:UTF-8 -*-
3
- import platform
4
-
5
- system_name = platform.system().lower()
6
- if system_name == 'windows':
7
- import asyncio
8
- asyncio.set_event_loop_policy(
9
- asyncio.WindowsSelectorEventLoopPolicy()
10
- )
11
-
1
+ #!/usr/bin/python
2
+ # -*- coding:UTF-8 -*-
3
+ import platform
4
+
5
+ system_name = platform.system().lower()
6
+ if system_name == 'windows':
7
+ import asyncio
8
+ asyncio.set_event_loop_policy(
9
+ asyncio.WindowsSelectorEventLoopPolicy()
10
+ )
11
+
crawlo/utils/tools.py CHANGED
@@ -1,5 +1,5 @@
1
- def custom_extractor_proxy(data: dict, key: str='proxy') -> dict | str | None:
2
- """只负责从 API 返回数据中提取代理部分"""
3
- if data.get("status") == 0:
4
- return data.get(key) # 返回 {"http": "...", "https": "..."} 整个字典
1
+ def custom_extractor_proxy(data: dict, key: str='proxy') -> dict | str | None:
2
+ """只负责从 API 返回数据中提取代理部分"""
3
+ if data.get("status") == 0:
4
+ return data.get(key) # 返回 {"http": "...", "https": "..."} 整个字典
5
5
  return None
crawlo/utils/url.py CHANGED
@@ -1,40 +1,40 @@
1
- from urllib.parse import urldefrag
2
- from w3lib.url import add_or_replace_parameter
3
-
4
-
5
- def escape_ajax(url: str) -> str:
6
- """
7
- 根据Google AJAX爬取规范转换URL(处理哈希片段#!):
8
- https://developers.google.com/webmasters/ajax-crawling/docs/getting-started
9
-
10
- 规则说明:
11
- 1. 仅当URL包含 `#!` 时才转换(表示这是AJAX可爬取页面)
12
- 2. 将 `#!key=value` 转换为 `?_escaped_fragment_=key%3Dvalue`
13
- 3. 保留原始查询参数(如果有)
14
-
15
- 示例:
16
- >>> escape_ajax("www.example.com/ajax.html#!key=value")
17
- 'www.example.com/ajax.html?_escaped_fragment_=key%3Dvalue'
18
- >>> escape_ajax("www.example.com/ajax.html?k1=v1#!key=value")
19
- 'www.example.com/ajax.html?k1=v1&_escaped_fragment_=key%3Dvalue'
20
- >>> escape_ajax("www.example.com/ajax.html#!")
21
- 'www.example.com/ajax.html?_escaped_fragment_='
22
-
23
- 非AJAX可爬取的URL(无#!)原样返回:
24
- >>> escape_ajax("www.example.com/ajax.html#normal")
25
- 'www.example.com/ajax.html#normal'
26
- """
27
- # 分离URL的基础部分和哈希片段
28
- de_frag, frag = urldefrag(url)
29
-
30
- # 仅处理以"!"开头的哈希片段(Google规范)
31
- if not frag.startswith("!"):
32
- return url # 不符合规则则原样返回
33
-
34
- # 调用辅助函数添加 `_escaped_fragment_` 参数
35
- return add_or_replace_parameter(de_frag, "_escaped_fragment_", frag[1:])
36
-
37
-
38
- if __name__ == '__main__':
39
- f = escape_ajax('http://example.com/page#!')
1
+ from urllib.parse import urldefrag
2
+ from w3lib.url import add_or_replace_parameter
3
+
4
+
5
+ def escape_ajax(url: str) -> str:
6
+ """
7
+ 根据Google AJAX爬取规范转换URL(处理哈希片段#!):
8
+ https://developers.google.com/webmasters/ajax-crawling/docs/getting-started
9
+
10
+ 规则说明:
11
+ 1. 仅当URL包含 `#!` 时才转换(表示这是AJAX可爬取页面)
12
+ 2. 将 `#!key=value` 转换为 `?_escaped_fragment_=key%3Dvalue`
13
+ 3. 保留原始查询参数(如果有)
14
+
15
+ 示例:
16
+ >>> escape_ajax("www.example.com/ajax.html#!key=value")
17
+ 'www.example.com/ajax.html?_escaped_fragment_=key%3Dvalue'
18
+ >>> escape_ajax("www.example.com/ajax.html?k1=v1#!key=value")
19
+ 'www.example.com/ajax.html?k1=v1&_escaped_fragment_=key%3Dvalue'
20
+ >>> escape_ajax("www.example.com/ajax.html#!")
21
+ 'www.example.com/ajax.html?_escaped_fragment_='
22
+
23
+ 非AJAX可爬取的URL(无#!)原样返回:
24
+ >>> escape_ajax("www.example.com/ajax.html#normal")
25
+ 'www.example.com/ajax.html#normal'
26
+ """
27
+ # 分离URL的基础部分和哈希片段
28
+ de_frag, frag = urldefrag(url)
29
+
30
+ # 仅处理以"!"开头的哈希片段(Google规范)
31
+ if not frag.startswith("!"):
32
+ return url # 不符合规则则原样返回
33
+
34
+ # 调用辅助函数添加 `_escaped_fragment_` 参数
35
+ return add_or_replace_parameter(de_frag, "_escaped_fragment_", frag[1:])
36
+
37
+
38
+ if __name__ == '__main__':
39
+ f = escape_ajax('http://example.com/page#!')
40
40
  print(f)
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: crawlo
3
+ Version: 1.1.1
4
+ Summary: Crawlo 是一款基于异步IO的高性能Python爬虫框架,支持分布式抓取。
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
+ # 🕷️ Crawlo - 轻量级异步爬虫框架
52
+
53
+ > 一个简洁、易用、可扩展的 Python 异步爬虫框架,灵感源自 Scrapy,但更轻量、更易上手。
54
+
55
+ 🚀 支持命令行操作、爬虫生成、合规检查、运行监控与统计分析,适合快速开发中小型爬虫项目。
56
+
57
+ ---
58
+
59
+ ## 📦 特性
60
+
61
+ - ✅ **命令行驱动**:`crawlo startproject`, `crawlo genspider` 等
62
+ - ✅ **自动发现爬虫**:无需手动注册,自动加载 `spiders/` 模块
63
+ - ✅ **异步核心**:基于 `asyncio` 实现高并发抓取
64
+ - ✅ **灵活配置**:通过 `crawlo.cfg` 和 `settings.py` 管理项目
65
+ - ✅ **爬虫检查**:`crawlo check` 验证爬虫定义是否合规
66
+ - ✅ **运行统计**:`crawlo stats` 查看历史运行指标(持久化存储)
67
+ - ✅ **批量运行**:支持 `crawlo run all` 启动所有爬虫
68
+ - ✅ **日志与调试**:结构化日志输出,便于排查问题
69
+
70
+ ---
71
+
72
+ ## 🚀 快速开始
73
+
74
+ ### 1. 安装 Crawlo
75
+
76
+ ```bash
77
+ pip install crawlo
78
+ ```
79
+
80
+ > ⚠️ 当前为开发阶段,建议使用源码安装:
81
+ >
82
+ > ```bash
83
+ > git clone https://github.com/yourname/crawlo.git
84
+ > pip install -e crawlo
85
+ > ```
86
+
87
+ ### 2. 创建项目
88
+
89
+ ```bash
90
+ crawlo startproject myproject
91
+ cd myproject
92
+ ```
93
+
94
+ 生成项目结构:
95
+
96
+ ```
97
+ myproject/
98
+ ├── crawlo.cfg
99
+ ├── myproject/
100
+ │ ├── __init__.py
101
+ │ ├── settings.py
102
+ │ └── spiders/
103
+ │ ├── __init__.py
104
+ │ └── (你的爬虫将在这里)
105
+ ```
106
+
107
+ ### 3. 生成爬虫
108
+
109
+ ```bash
110
+ crawlo genspider example example.com
111
+ ```
112
+
113
+ 生成 `spiders/example.py`:
114
+
115
+ ```python
116
+ class ExampleSpider(Spider):
117
+ name = "example"
118
+ start_urls = ["https://example.com"]
119
+
120
+ def parse(self, response):
121
+ # 解析逻辑
122
+ pass
123
+ ```
124
+
125
+ ### 4. 检查爬虫合规性
126
+
127
+ ```bash
128
+ crawlo check
129
+ ```
130
+
131
+ 输出示例:
132
+
133
+ ```
134
+ 🔍 Checking 1 spider(s)...
135
+ ✅ example ExampleSpider (OK)
136
+ 🎉 All spiders are compliant!
137
+ ```
138
+
139
+ ### 5. 运行爬虫
140
+
141
+ ```bash
142
+ # 运行单个爬虫
143
+ crawlo run example
144
+
145
+ # 运行所有爬虫
146
+ crawlo run all
147
+ ```
148
+
149
+ ### 6. 查看运行统计
150
+
151
+ ```bash
152
+ crawlo stats
153
+ ```
154
+
155
+ 查看最近一次运行的请求、响应、项目数等指标:
156
+
157
+ ```
158
+ 📊 Recent Spider Statistics (last run):
159
+ 🕷️ example
160
+ downloader/request_count 1
161
+ item_scraped_count 1
162
+ log_count/INFO 7
163
+ ```
164
+
165
+ ---
166
+
167
+ ## 🛠️ 命令列表
168
+
169
+ | 命令 | 说明 |
170
+ |------|------|
171
+ | `crawlo startproject <name>` | 创建新项目 |
172
+ | `crawlo genspider <name> <domain>` | 生成爬虫模板 |
173
+ | `crawlo list` | 列出所有已注册的爬虫 |
174
+ | `crawlo check` | 检查爬虫定义是否合规 |
175
+ | `crawlo run <spider_name>` | 运行指定爬虫 |
176
+ | `crawlo run all` | 运行所有爬虫 |
177
+ | `crawlo stats` | 查看最近运行的统计信息 |
178
+ | `crawlo stats <spider_name>` | 查看指定爬虫的统计 |
179
+
180
+ ---
181
+
182
+ ## 📁 项目结构说明
183
+
184
+ ```ini
185
+ # crawlo.cfg
186
+ [settings]
187
+ default = myproject.settings
188
+ ```
189
+
190
+ ```python
191
+ # settings.py
192
+ BOT_NAME = "myproject"
193
+ LOG_LEVEL = "DEBUG"
194
+ CONCURRENT_REQUESTS = 3
195
+ DOWNLOAD_DELAY = 1.0
196
+ # 其他配置...
197
+ ```
198
+
199
+ ---
200
+
201
+ ## 📊 统计持久化
202
+
203
+ 每次爬虫运行结束后,统计信息会自动保存到:
204
+
205
+ ```
206
+ logs/stats/<spider_name>_YYYYMMDD_HHMMSS.json
207
+ ```
208
+
209
+ 可通过 `crawlo stats` 命令读取,支持跨进程查看。
210
+
211
+ ---
212
+
213
+ ## 🧪 开发者提示
214
+
215
+ - 确保 `spiders/__init__.py` 中导入了你的爬虫类,否则无法被发现
216
+ - 使用 `get_project_root()` 自动定位项目根目录(通过查找 `crawlo.cfg`)
217
+ - 所有命令行工具均支持直接运行:`python -m crawlo.commands.list`
218
+
219
+ ---
220
+
@@ -0,0 +1,100 @@
1
+ crawlo/__init__.py,sha256=zOGI9hnWawIl0QA0Hnjmqo7vfd-WXNevOP9nLCq04XA,811
2
+ crawlo/__version__.py,sha256=q8_5C0f-8mHWNb6mMw02zlYPnEGXBqvOmP3z0CEwZKM,22
3
+ crawlo/cli.py,sha256=CtR2Pfa7SyRxEKPaXqt-6E6K5Vq5z3rfdAI95UO4cbU,1166
4
+ crawlo/crawler.py,sha256=xwViGsJutKjAvfrYlMUd0NQKQtBX2r5qNMvpWkujxTs,19558
5
+ crawlo/event.py,sha256=7-y6HNv_EIJSYQNzsj0mVK-Gg4ON3wdQeMdQjfFJPlw,313
6
+ crawlo/exceptions.py,sha256=pthF1lJlJHyRZm-mE6NAo5WzK3GYJqmRqIuIlK1Odx8,1129
7
+ crawlo/project.py,sha256=xWN2eTAjf_Pza-wWvvV4JjScQRWxe9hXlztX81ccUMc,5182
8
+ crawlo/stats_collector.py,sha256=NkO09CB-220qz5rxFcD_dedGfr2VPFrDo4hya0Zh8Qc,1577
9
+ crawlo/subscriber.py,sha256=3d4eYtkSgPj-18-mTZM6RQLSil-ux13FUcmfFxr3sMk,3730
10
+ crawlo/task_manager.py,sha256=AS7Xu_8Q_eb3jg9QSkK_wv6W1rRXaI6WjDp8p6h9ltU,721
11
+ crawlo/commands/__init__.py,sha256=AMYjXG7ulE8dPVmgWVo0uqXsaCYUUZYmmu2-7kFzH1M,342
12
+ crawlo/commands/check.py,sha256=172OiAxnX5wwSlszUsyPgMZwAoIbGDTdfhtRz309ilc,22843
13
+ crawlo/commands/genspider.py,sha256=In7X463vFCDhow73Netb4S1Vug_E0VC-1sevDc5nmSA,4267
14
+ crawlo/commands/list.py,sha256=P4O9zma8RA0061B2t8hRgz6FtRzINJRPbeWH7m6TZRg,5091
15
+ crawlo/commands/run.py,sha256=8Qngjsl8Q4RBdO39a__wKGsheY2PFuPit2hds_jwEbM,10524
16
+ crawlo/commands/startproject.py,sha256=lu7_E_ygnM-S5LsViuHoaCdJubFGIY5ecWLL-g3R8A8,3953
17
+ crawlo/commands/stats.py,sha256=6pAgkEi8MBnCer2rWmKpaTYr1jaM6HeMG9owAvEzJyY,6064
18
+ crawlo/core/__init__.py,sha256=PnFyJdVNHBoPmV1sW0AHQXijeoSTQ8cMYrbNM1JK8kA,41
19
+ crawlo/core/engine.py,sha256=xBYi-V1O3IfZU9Qo1TJynOpoMjdP_h8kmHC4iDbVfwE,5868
20
+ crawlo/core/processor.py,sha256=qmCqAeqhwYu-UE86evYesaGt9qpuSIfH-ZIZKcXFCZc,1140
21
+ crawlo/core/scheduler.py,sha256=oxVzdXvU0CDRfUFkv2MP0NvTRfTGbcvoz-__dNy_rzU,1885
22
+ crawlo/downloader/__init__.py,sha256=ukrDBULCaoDWoMLCO3XcQhDoasF0oUzj0PHnJ_ACJaE,2306
23
+ crawlo/downloader/aiohttp_downloader.py,sha256=ZxeKvWyAYzKCwu_yRfduX0hSwU3TEqvhBQaB9UBpzNE,7476
24
+ crawlo/downloader/cffi_downloader.py,sha256=j_LHvGxrQ9Ynod9RYp79vPgHlwKPPNc6NH8cN5hk-pk,10052
25
+ crawlo/downloader/httpx_downloader.py,sha256=fuienQkkn2yQ9R4RlvrxxWqX7OlChJSBEP11-5wNboY,11508
26
+ crawlo/extension/__init__.py,sha256=PEBbMxi6ULBZ9ivEJ4T7IH_R376BQJ6Rz_D9Ce-Cqbs,1133
27
+ crawlo/extension/log_interval.py,sha256=S-hSoiz9GdmgHrac4vDQ52fleoBcH-kzdPUD8YRAons,1922
28
+ crawlo/extension/log_stats.py,sha256=VinABjzuFa-JmNXSX86gQ_3Oyx1y3vUhpWTEu9HRRqg,1677
29
+ crawlo/extension/logging_extension.py,sha256=Jce2HHc9ejsIWQitkHZuhnLbT_1MIfcvywfzYkkJ5eY,1202
30
+ crawlo/filters/__init__.py,sha256=BCZl86BHiTfDGRe_b1TlNSr6pfNbMKTu0Uq0j4gX_1Q,977
31
+ crawlo/filters/aioredis_filter.py,sha256=tlkKe7pdXxFEjFBl8UN07JHn_QbOJNY3y3BRj6uFXpg,5471
32
+ crawlo/filters/memory_filter.py,sha256=bs2WUe7CdHiXgr344vzDqMfBv1b3RwXJMnwxpDb64Pw,6639
33
+ crawlo/items/__init__.py,sha256=bqekZrRlDhxfWie0UbCs656TptYseoe9QJ67I4E7Elk,386
34
+ crawlo/items/base.py,sha256=tAYrPJgblp3ZEihDXvappdYc6pGdim6x2_9QSmMKI2o,577
35
+ crawlo/items/fields.py,sha256=wMlakQTsEwyrlLzMt1gI4pScLQZMqd3E1xcfH4dbSqk,1801
36
+ crawlo/items/items.py,sha256=e-3nXI9ckD64vcDxxQiAU6ufbtJMs09gbZQcYjxgwHY,3374
37
+ crawlo/middleware/__init__.py,sha256=ldaGFNbiJnK9Fx12Vdf9fDNfzXxoETtShp5r-vodtw0,549
38
+ crawlo/middleware/default_header.py,sha256=i_Uj07JObyeZFxL7ZAZmvZsHvA1HGtkNab1sA0d-nWI,1067
39
+ crawlo/middleware/download_delay.py,sha256=2M-TchDA7MwyTfYy0Hzh_bW9wlHlpiP-oQlys7crTj0,966
40
+ crawlo/middleware/middleware_manager.py,sha256=j1hkWRFB5rnC5SnB7oXWE5eUNv8blS9krDIDM5fIDs8,6213
41
+ crawlo/middleware/proxy.py,sha256=3msCHiPgaaKt6vRjnNswkwSzUFrO4a8OgL9BeV42ySg,9555
42
+ crawlo/middleware/request_ignore.py,sha256=QI2z4fUnJ-4xvPTZAmsL-GqR4RFHS1xq9iDr5KFrMco,997
43
+ crawlo/middleware/response_code.py,sha256=tmef2QVl3JCiTMii6VQkASlOY2OyqmOPoOfNxIK1eF8,659
44
+ crawlo/middleware/response_filter.py,sha256=ep8ZxDlfIefi9YqK8dPASEp5TTDRo9QEY_jMceC411s,837
45
+ crawlo/middleware/retry.py,sha256=6I0FXJ4zCnJ-pMBxoc8Cg4OVCcH4Buyfoy6ivSu9bro,3369
46
+ crawlo/network/__init__.py,sha256=VaD0GmsgDYJ8UMgrtjeOc1Wc7lDGee1uAF3neRpyug0,123
47
+ crawlo/network/request.py,sha256=JD4p9e0osjAFb40Ux57NVJliUe7NQ6_IxoMwj4faczs,7044
48
+ crawlo/network/response.py,sha256=_oaElq7_Y-5gz2k8lhfZIss7hxFh6dJ77OpuXZXr9oI,6034
49
+ crawlo/pipelines/__init__.py,sha256=Hk-M6X0VCGLp6OEdgnhXGhGhKS5TjKf6dkg8bU9pvUE,260
50
+ crawlo/pipelines/console_pipeline.py,sha256=KABkR3J-rqO0Awox7lizxKR2XuHfVhWPiVRgIybwwu4,1248
51
+ crawlo/pipelines/mongo_pipeline.py,sha256=lv-Zn_mWdE_jVy7Nh30Lzqm3YhtLRV5rMy-m4rBWYe0,4442
52
+ crawlo/pipelines/mysql_batch_pipline.py,sha256=C7EPzAluY-Kplc6MB2UYLLDdahYsnZMZf3cxQ5vloeQ,10339
53
+ crawlo/pipelines/mysql_pipeline.py,sha256=6g6PGTwAyzH5VStlPAg2SdG5t1lPw1Zu-cY7x6Mz16s,7861
54
+ crawlo/pipelines/pipeline_manager.py,sha256=VrbebOYiqrobtKhp5II18w-odCICdWkmRg5WPK0Emz4,2112
55
+ crawlo/settings/__init__.py,sha256=xsukVKn_h2Hopm1Nj-bXkhbfyS62QTTvJi7fhZUwR9M,123
56
+ crawlo/settings/default_settings.py,sha256=BDpjZkPYQhuutxZomWYS6WvBHomKfHdNVSvTmyz1bKY,7100
57
+ crawlo/settings/setting_manager.py,sha256=SxKB1aCWh4OySM_bH9cYng9I3PAmrSP-Q8XOZEWEwbI,2899
58
+ crawlo/spider/__init__.py,sha256=kNBJ02QB0EZcGvzMH6GYh5UssI1HzOREIHz3FVo8LOA,3854
59
+ crawlo/templates/crawlo.cfg.tmpl,sha256=9BAmwEibS5Tvy6HIcGXPb0BGeuesmibebmTW0iAEkmo,230
60
+ crawlo/templates/project/__init__.py.tmpl,sha256=f3ETIXw_O6K-lkL6lXM5znMPJW1FZYGFrwDs2BnHcnQ,58
61
+ crawlo/templates/project/items.py.tmpl,sha256=3h-4nuneUoCAGUzSLyLNsdgeAAUXzz4rV0QctzCkIJA,301
62
+ crawlo/templates/project/middlewares.py.tmpl,sha256=oy5RCkRqLeBpvtYA1NGVlbYfl8rWuS3VDgQSx5opnHQ,2102
63
+ crawlo/templates/project/pipelines.py.tmpl,sha256=unEag7_qMN5DiffIzTKRmTVUCiTkHGCEad-jRQ6eH4I,1817
64
+ crawlo/templates/project/settings.py.tmpl,sha256=By0YaZPxAP0pha_oY7J-vm9ntuvEfJO1jTiUhNddGic,1716
65
+ crawlo/templates/project/spiders/__init__.py.tmpl,sha256=j_YKsw6HQMJyqlk3WUouP3bsr-XVxshRoSNakHBc00g,106
66
+ crawlo/templates/spider/spider.py.tmpl,sha256=nyFMfk6qsmwfGuuNEcu6N6VnrOtq1GHVcoJOYRHrZFA,838
67
+ crawlo/utils/__init__.py,sha256=BDORpyjMN7VGPKImnCDKSkprS-petgD7ezc9rMlBvb0,123
68
+ crawlo/utils/date_tools.py,sha256=0yG0tzGb1VFgWDJJ_cow2LJfz3kj_w2MqSjmfKKESl8,6961
69
+ crawlo/utils/db_helper.py,sha256=3ib5-agrlwf2t5S_QtLRYH75wvJDlYbRqRmDEbpH5Bo,10559
70
+ crawlo/utils/func_tools.py,sha256=WUZEGpWMuDDX7g-QySM7iaiC74erW2SSkZoUvDw1NjM,2369
71
+ crawlo/utils/log.py,sha256=A3lPyhD8kD88cV23KOL-_eT8g69xGQ5L1toDB2AO0mc,4005
72
+ crawlo/utils/pqueue.py,sha256=4Ymkm38fRFqEcSJeD_ULkuBaCk6QdYvJdnYvtJjh-Tk,5386
73
+ crawlo/utils/request.py,sha256=yoLB2rY8d78vgPjIWpdhY5SalIKjyLIvTG_UH6EMdVI,8798
74
+ crawlo/utils/spider_loader.py,sha256=pEDUsYOTGjszA6KgjiMlYN4GS5fP4uakkhcp3JTFFQY,2187
75
+ crawlo/utils/system.py,sha256=HvWV1acxou0Rn0L7pNq4CnV_GWFeU0Tmjy3_nLD8M64,237
76
+ crawlo/utils/tools.py,sha256=5Uv25Wy4m_ndZY0-n-eX-t3PxvaZ6wR3-Wvx-o7_Vrs,271
77
+ crawlo/utils/url.py,sha256=rlgX2VlJv6JvLmCDTsbxzMSXE6R5ZL_0dLEqprsA-JU,1482
78
+ examples/__init__.py,sha256=6i631BPnS_TR_BWUjtjB5CBO-zv9kRkwQTQvSya2wHE,123
79
+ examples/baidu_spider/__init__.py,sha256=xlj0-TBQBhcKglllla_bQbufNiv10UFE0KsWMLvzFz4,123
80
+ examples/baidu_spider/demo.py,sha256=MTEHkm7U4Kyx5QULCgR6to391xn4XPay6fmuV1c1uRc,24278
81
+ examples/baidu_spider/items.py,sha256=e_LNs13SFiKkqwP2sdKhX72XkiX-E-ythMQOsY5P8IA,1264
82
+ examples/baidu_spider/middleware.py,sha256=I71ZMmWTiDBFq4t2zfTE7IIXCqwaaeQ1DvKGW70q2Yg,1397
83
+ examples/baidu_spider/pipeline.py,sha256=TUK_LnrU818UYmCn2_gKeNaTZjaj9qjrlndRLsR4wf0,1437
84
+ examples/baidu_spider/run.py,sha256=7ifJVryShJ41rnlcdzU6rfex8L0Av1XpeSo4DhRRH6w,564
85
+ examples/baidu_spider/settings.py,sha256=GOnHyYCSyOacCTn-sFAptNR3oSBpWxrGf1XkVHLaeng,3925
86
+ examples/baidu_spider/spiders/__init__.py,sha256=eJ_ih4GiGfwQzPILeouy1Hnc4BrPz0KNPYlLHYvrvoc,123
87
+ examples/baidu_spider/spiders/bai_du.py,sha256=pw4WccbmBR07CuSqCgm_7x9SH63FDJS_sXSaN5Ew5Tw,1589
88
+ examples/baidu_spider/spiders/miit.py,sha256=RStlK5GdrILhqTRNpeWlP_jCijWPUpmmN7Sq6ua_K3s,6338
89
+ examples/baidu_spider/spiders/sina.py,sha256=Q1TwvwutfGdFZzMIDyppOlwQIdr4bQSd2m42iNP8T5o,2418
90
+ tests/__init__.py,sha256=scL1IPVT1iucth7v8ffrjRdeW7QrC_Y7AMmFVMdTY1Y,129
91
+ tests/test_proxy_health_check.py,sha256=xo3QMP1YNw9hu7JDHZOYCUZmFFKLJpHSh4SbxXhCRPQ,1091
92
+ tests/test_proxy_middleware_integration.py,sha256=zcl7fR9Toc-I-stSUTzKZPwcfh3kgrpjI5SbkZ6AVmE,4305
93
+ tests/test_proxy_providers.py,sha256=XwWZCywTYguSsUxSm6fsbaoH1p9dKjqSIx9-sqKZehA,1693
94
+ tests/test_proxy_stats.py,sha256=Til_yksrRz2yBVw-yJi5-36LhNW3vTwpXTm4BdR9PUM,507
95
+ tests/test_proxy_strategies.py,sha256=ZkziozkvZd3KWOQnpHQ8Upd3WpyoX7gN0qFGluNm348,1809
96
+ crawlo-1.1.1.dist-info/METADATA,sha256=t26VSUHs-38nd7L3JdSmD4zCICOUCv8aHFUSsvvLgIs,5347
97
+ crawlo-1.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
98
+ crawlo-1.1.1.dist-info/entry_points.txt,sha256=5HoVoTSPxI8SCa5B7pQYxLSrkOdiunyO9tqNsLMv52g,43
99
+ crawlo-1.1.1.dist-info/top_level.txt,sha256=keG_67pbZ_wZL2dmDRA9RMaNHTaV_x_oxZ9DKNgwvR0,22
100
+ crawlo-1.1.1.dist-info/RECORD,,
examples/__init__.py CHANGED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/python
2
+ # -*- coding:UTF-8 -*-
3
+ """
4
+ # @Time : 2025-02-05 12:36
5
+ # @Author : oscar
6
+ # @Desc : None
7
+ """
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/python
2
+ # -*- coding:UTF-8 -*-
3
+ """
4
+ # @Time : 2025-02-05 13:05
5
+ # @Author : oscar
6
+ # @Desc : None
7
+ """
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/python
2
+ # -*- coding:UTF-8 -*-
3
+ """
4
+ # @Time : 2025-07-14 13:04
5
+ # @Author : crawl-coder
6
+ # @Desc : None
7
+ """
8
+ import asyncio
9
+ import asyncmy
10
+ from datetime import datetime
11
+ import logging
12
+
13
+ from settings import MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_TABLE, MYSQL_DB
14
+
15
+ # 配置日志
16
+ logging.basicConfig(
17
+ level=logging.INFO,
18
+ format='%(asctime)s - %(levelname)s - %(message)s'
19
+ )
20
+ logger = logging.getLogger(__name__)
21
+
22
+ # 测试数据
23
+ value_tuples = [('3250219', '煤炭开采板块午后直线拉升 郑州煤电涨停', '煤炭开采板块午后直线拉升,()涨停,()、()、()、()、()等纷纷走高。消息面上,中国煤炭运销协会表示,加强行业自律,整治内卷式竞争,促进煤炭市场供需平衡。', '煤炭开采板块午后直线拉升,郑州煤电涨停,山煤国际、辽宁能源、华电能源、恒源煤电、盘江股份等纷纷走高。消息面上,中国煤炭运销协会表示,加强行业自律,整治内卷式竞争,促进煤炭市场供需平衡。', 'https://news.10jqka.com.cn/20250714/c669607368.shtml', '异动', '2025-07-14 13:04:07', ''), ('3250025', '现货白银日内涨幅扩大至1.00%,现报38.77美元/盎司', '现货白银日内涨幅扩大至1.00%,现报38.77美元/盎司。', '现货白银日内涨幅扩大至1.00%,现报38.77美元/盎司。', 'https://news.10jqka.com.cn/20250714/c669606752.shtml', 'A股', '2025-07-14 11:59:10', ''), ('3250061', '7月14日午间公告一览:晨化股份使用3000万元闲置资金购买理财产品', '()公告,公司及子公司近日使用自有闲置资金购买了3000万元的理财产品。此次投资包括两个金额各为1500万元的银河盛汇稳健1号集合资产管理计划,预期年化收益率为3.2%。该理财产品的起息日为2025年7月10日,到期日为2026年7月6日。公司表示,此举是在确保日常运营和资金安全的前提下进行的,不会影响公司主营业务的正常开展,旨在提高资金使用效率,获取较好的投资回报。', '晨化股份公告,公司及子公司近日使用自有闲置资金购买了3000万元的理财产品。此次投资包括两个金额各为1500万元的银河盛汇稳健1号集合资产管理计划,预期年化收益率为3.2%。该理财产品的起息日为2025年7月10日,到期日为2026年7月6日。公司表示,此举是在确保日常运营和资金安全的前提下进行的,不会影响公司主营业务的正常开展,旨在提高资金使用效率,获取较好的投资回报。', 'https://news.10jqka.com.cn/20250714/c669606926.shtml', '公告,A股', '2025-07-14 12:15:33', ''), ('3250123', '鸿蒙智行问界产品总监彭磊调任享界系列产品总监', '7月14日,鸿蒙智行App显示,彭磊认证信息已变更为享界系列产品总监。此前担任鸿蒙智行问界产品总监的彭磊今天开始在微博发文预热享界产品,宣传鸿蒙智行享界第二款车享界S9T。不过,他的微博认证未同步更新,仍为鸿蒙智行问界产品总监。', '7月14日,鸿蒙智行App显示,彭磊认证信息已变更为享界系列产品总监。此前担任鸿蒙智行问界产品总监的彭磊今天开始在微博发文预热享界产品,宣传鸿蒙智行享界第二款车享界S9T。不过,他的微博认证未同步更新,仍为鸿蒙智行问界产品总监。', 'https://news.10jqka.com.cn/20250714/c669607077.shtml', '港股,A股', '2025-07-14 12:34:46', ''), ('3250153', '韩国前总统尹锡悦再次未出席内乱特检组传唤调查', '记者获悉,韩国前总统尹锡悦14日再次未出席内乱特检组的传唤调查。(央视新闻)', '记者获悉,韩国前总统尹锡悦14日再次未出席内乱特检组的传唤调查。(央视新闻)', 'https://news.10jqka.com.cn/20250714/c669607226.shtml', '美股,港股,A股', '2025-07-14 12:48:40', ''), ('3250135', '立讯精密旗下立铠精密在黄石成立新公司', '企查查APP显示,近日,立铠精密科技(黄石)有限公司成立,法定代表人为杨立强,注册资本5亿元,经营范围包括移动终端设备销售、互联网设备销售、汽车零部件及配件制造等。企查查股权穿透显示,该公司由立铠精密科技(盐城)有限公司全资持股,后者大股东为()。', '企查查APP显示,近日,立铠精密科技(黄石)有限公司成立,法定代表人为杨立强,注册资本5亿元,经营范围包括移动终端设备销售、互联网设备销售、汽车零部件及配件制造等。企查查股权穿透显示,该公司由立铠精密科技(盐城)有限公司全资持股,后者大股东为立讯精密。', 'https://news.10jqka.com.cn/20250714/c669607154.shtml', 'A股', '2025-07-14 12:40:40', ''), ('3250197', '沪深京三市成交额超1万亿元 较上日此时缩量686亿元', '据()iFinD数据,沪深京三市成交额超1万亿元,较上日此时686亿元,预计全天成交金额约1.6万亿元。截至目前,沪市成交额4158亿元,深市成交额5688亿元,北证50成交额154亿元。', '据同花顺iFinD数据,沪深京三市成交额超1万亿元,较上日此时缩量686亿元,预计全天成交金额约1.6万亿元。截至目前,沪市成交额4158亿元,深市成交额5688亿元,北证50成交额154亿元。', 'https://news.10jqka.com.cn/20250714/c669607345.shtml', 'A股', '2025-07-14 13:01:38', ''), ('3250129', '伟仕佳杰:公司已开始探索稳定币支付及结算解决方案', '伟仕佳杰在港交所发布公告称,本公司日前已开始进行合作洽谈,以探索稳定币支付及结算的解决方案。该合作讨论主要聚焦本公司在东南亚地区的ICT产品分销、供应链服务及数位生态业务,本次合作讨论不涉及任何加密货币投机行为。该讨论处于初步阶段,且尚未达成任何具法律约束力的协定。', '伟仕佳杰在港交所发布公告称,本公司日前已开始进行合作洽谈,以探索稳定币支付及结算的解决方案。该合作讨论主要聚焦本公司在东南亚地区的ICT产品分销、供应链服务及数位生态业务,本次合作讨论不涉及任何加密货币投机行为。该讨论处于初步阶段,且尚未达成任何具法律约束力的协定。', 'https://news.10jqka.com.cn/20250714/c669607132.shtml', '港股', '2025-07-14 12:37:13', ''), ('3250065', '海南航空发声明打假', '海南航空今日在网络社交平台发布声明。声明称,近期发现部分网络平台及线下场所存在商户和个人未经授权,擅自盗用海南航空商标或公司名称,公然冒充公司员工或关联方,非法开展销售活动。所售商品涵盖空乘制服、飞机模型、机上用品、周边文创产品等多个品类。更有甚者,疑似穿着海南航空享有专利保护的乘务员制服,在直播平台上大肆赚取流量、非法牟利,严重扰乱市场正常秩序。声明表示,“海南航空官方商品及服务仅通过海南航空官网、官方App、经我司正式授权的直营渠道以及指定的合作方进行发布与销售。任何单位或个人均无权擅自使用我司依法享有的商标、名称、专利、著作权等知识产权,更不得假冒我司员工身份开展任何商业活动。”声明还指出,如在日常生活或网络浏览过程中遇到可疑情况,可随时拨打海南航空服务热线95339进行咨询核实,或通过官方网站在线客服反馈相关线索。如未经核实在非正规渠道购买海南航空服务或相关产品,海南航空将不会履行相关义务或承担任何赔偿责任。', '海南航空今日在网络社交平台发布声明。声明称,近期发现部分网络平台及线下场所存在商户和个人未经授权,擅自盗用海南航空商标或公司名称,公然冒充公司员工或关联方,非法开展销售活动。所售商品涵盖空乘制服、飞机模型、机上用品、周边文创产品等多个品类。更有甚者,疑似穿着海南航空享有专利保护的乘务员制服,在直播平台上大肆赚取流量、非法牟利,严重扰乱市场正常秩序。 声明表示,“海南航空官方商品及服务仅通过海南航空官网、官方 App、经我司正式授权的直营渠道以及指定的合作方进行发布与销售。任何单位或个人均无权擅自使用我司依法享有的商标、名称、专利、著作权等知识产权,更不得假冒我司员工身份开展任何商业活动。” 声明还指出,如在日常生活或网络浏览过程中遇到可疑情况,可随时拨打海南航空服务热线 95339 进行咨询核实,或通过官方网站在线客服反馈相关线索。如未经核实在非正规渠道购买海南航空服务或相关产品,海南航空将不会履行相关义务或承担任何赔偿责任。', 'https://news.10jqka.com.cn/20250714/c669606930.shtml', '美股,港股,A股', '2025-07-14 12:15:49', ''), ('3250067', '陕西科研团队光镊切片显微术破解悬浮细胞三维观测难题 成果有望用于医学成像等领域', '据中国科学院西安光机所消息,该所超快光科学与技术全国重点实验室研究员姚保利、徐孝浩团队在生物光学显微成像及微操纵方面取得重要进展,提出了“光镊切片显微术”,实现了悬浮生物细胞的全光式三维成像,为光镊技术开拓了新应用方向,在类器官构建、三维中性原子阵列组装、细胞自动化识别及分选方面具有巨大应用潜力。上述成果在国际顶级学术期刊《科学进展》发表。(科创板日报)', '据中国科学院西安光机所消息,该所超快光科学与技术全国重点实验室研究员姚保利、徐孝浩团队在生物光学显微成像及微操纵方面取得重要进展,提出了“光镊切片显微术”,实现了悬浮生物细胞的全光式三维成像,为光镊技术开拓了新应用方向,在类器官构建、三维中性原子阵列组装、细胞自动化识别及分选方面具有巨大应用潜力。上述成果在国际顶级学术期刊《科学进展》发表。(科创板日报)', 'https://news.10jqka.com.cn/20250714/c669606940.shtml', '港股,A股', '2025-07-14 12:16:39', ''), ('3250121', '公安部:2025年上半年全国机动车达4.6亿辆 驾驶人达5.5亿人', '公安部统计,截至2025年6月底,全国机动车保有量达4.6亿辆,其中汽车3.59亿辆;机动车驾驶人5.5亿人,其中汽车驾驶人5.15亿人。2025年上半年全国新注册登记机动车1688万辆,新领证驾驶人1258万人。上半年新注册登记机动车1688万辆,新注册登记汽车1250万辆。2025年上半年,全国新注册登记机动车1688万辆。其中,汽车新注册登记1250万辆,同比增长0.68%。新能源汽车保有量达3689万辆,上半年新注册登记562.2万辆。截至6月底,全国新能源汽车保有量达3689万辆,占汽车总量的10.27%。其中,纯电动汽车保有量2553.9万辆,占新能源汽车总量的69.23%。上半年新注册登记新能源汽车562.2万辆,同比增长27.86%,创历史新高。新能源汽车新注册登记量占汽车新注册登记量的44.97%。(央视新闻)', '公安部统计,截至2025年6月底,全国机动车保有量达4.6亿辆,其中汽车3.59亿辆;机动车驾驶人5.5亿人,其中汽车驾驶人5.15亿人。2025年上半年全国新注册登记机动车1688万辆,新领证驾驶人1258万人。上半年新注册登记机动车1688万辆,新注册登记汽车1250万辆。2025年上半年,全国新注册登记机动车1688万辆。其中,汽车新注册登记1250万辆,同比增长0.68%。新能源汽车保有量达3689万辆,上半年新注册登记562.2万辆。截至6月底,全国新能源汽车保有量达3689万辆,占汽车总量的10.27%。其中,纯电动汽车保有量2553.9万辆,占新能源汽车总量的69.23%。上半年新注册登记新能源汽车562.2万辆,同比增长27.86%,创历史新高。新能源汽车新注册登记量占汽车新注册登记量的44.97%。(央视新闻)', 'https://news.10jqka.com.cn/20250714/c669607063.shtml', '港股,A股', '2025-07-14 12:33:07', ''), ('3250099', '全国首单低空运营管理责任险落地苏州', '全国首个面向低空经济运营管理方的保险“安翼计划”近日在苏州落地。该保险方案由苏州东吴财产保险股份有限公司联合中国财产再保险有限责任公司研发,为苏州市盛泽湖全空间无人体系示范岛的试飞运营场地管理方提供风险保障。“安翼计划”针对低空经济运营中特有的信号干扰、操作失误、外部撞击等风险场景,提供精细化、专业化风险解决方案,将保险保障聚焦于低空运营管理方,系统构建了覆盖场地方责任、低空运营管理风险的完整保障体系。(新华日报)', '全国首个面向低空经济运营管理方的保险“安翼计划”近日在苏州落地。该保险方案由苏州东吴财产保险股份有限公司联合中国财产再保险有限责任公司研发,为苏州市盛泽湖全空间无人体系示范岛的试飞运营场地管理方提供风险保障。“安翼计划”针对低空经济运营中特有的信号干扰、操作失误、外部撞击等风险场景,提供精细化、专业化风险解决方案,将保险保障聚焦于低空运营管理方,系统构建了覆盖场地方责任、低空运营管理风险的完整保障体系。(新华日报)', 'https://news.10jqka.com.cn/20250714/c669607049.shtml', '美股,港股,A股', '2025-07-14 12:30:52', ''), ('3250159', '韩正会见印度外长苏杰生', '据新华社报道,7月14日,国家副主席韩正在北京会见印度外长苏杰生。韩正表示,去年10月,习近平主席同莫迪总理在喀山成功会晤,引领中印关系重启再出发。中印都是发展中大国、全球南方重要成员,做相互成就的伙伴,实现“龙象共舞”,是双方正确选择。双方要进一步落实两国领导人达成的重要共识,坚持高层引领、稳步推进务实合作、尊重彼此关切,推动中印关系持续健康稳定发展。苏杰生表示,莫迪总理同习近平主席喀山会晤后,印中关系稳步改善。印方愿以领导人共识为指引,保持印中关系发展势头,推进互利合作,加强在多边机制中的沟通协调。印方支持中方作为轮值主席国办好今年的上海合作组织峰会。', '据新华社报道,7月14日,国家副主席韩正在北京会见印度外长苏杰生。韩正表示,去年10月,习近平主席同莫迪总理在喀山成功会晤,引领中印关系重启再出发。中印都是发展中大国、全球南方重要成员,做相互成就的伙伴,实现“龙象共舞”,是双方正确选择。双方要进一步落实两国领导人达成的重要共识,坚持高层引领、稳步推进务实合作、尊重彼此关切,推动中印关系持续健康稳定发展。苏杰生表示,莫迪总理同习近平主席喀山会晤后,印中关系稳步改善。印方愿以领导人共识为指引,保持印中关系发展势头,推进互利合作,加强在多边机制中的沟通协调。印方支持中方作为轮值主席国办好今年的上海合作组织峰会。', 'https://news.10jqka.com.cn/20250714/c669607238.shtml', '美股,港股,A股', '2025-07-14 12:50:33', ''), ('3250059', '泰国机构将2025年到访游客人数预估从4000万人次下调至3500万人次', '泰国机构将2025年到访游客人数预估从4000万人次下调至3500万人次。', '泰国机构将2025年到访游客人数预估从4000万人次下调至3500万人次。', 'https://news.10jqka.com.cn/20250714/c669606902.shtml', 'A股', '2025-07-14 12:13:04', ''), ('3250131', '宇树科技获得出版物零售许可', '天眼查App显示,7月4日,杭州宇树科技股份有限公司新增一则行政许可信息,许可内容为出版物零售,许可机关为区党委宣传部(区新闻出版局)。值得注意的是,今年5月,该公司经营范围新增出版物零售。', '天眼查App显示,7月4日,杭州宇树科技股份有限公司新增一则行政许可信息,许可内容为出版物零售,许可机关为区党委宣传部(区新闻出版局)。值得注意的是,今年5月,该公司经营范围新增出版物零售。', 'https://news.10jqka.com.cn/20250714/c669607142.shtml', '港股,A股', '2025-07-14 12:38:20', ''), ('3250079', '韩特检组对军方24处场所展开扣押搜查,正式调查尹锡悦外患罪嫌疑', '韩国内乱特检组于7月14日对军方无人机作战司令部、国防部、国防部防间谍司令部等24处军事相关场所进行了全方位的扣押搜查,对前总统尹锡悦涉嫌外患罪的情况展开正式调查。搜查地点还包括国家安保室、驻白翎岛部队、无人机作战司令部司令金龙大的住宅等。(央视新闻)', '韩国内乱特检组于7月14日对军方无人机作战司令部、国防部、国防部防间谍司令部等24处军事相关场所进行了全方位的扣押搜查,对前总统尹锡悦涉嫌外患罪的情况展开正式调查。搜查地点还包括国家安保室、驻白翎岛部队、无人机作战司令部司令金龙大的住宅等。(央视新闻)', 'https://news.10jqka.com.cn/20250714/c669607015.shtml', '美股,港股,A股', '2025-07-14 12:26:27', ''), ('3250125', '中国中铁在秦皇岛成立新公司 含海洋服务业务', '企查查APP显示,近日,中铁大桥局集团(秦皇岛)供应链管理有限公司成立,法定代表人为何士博,注册资本为100万元,经营范围包含:供应链管理服务;工程管理服务;海洋服务;海洋工程装备销售;金属结构销售等。企查查股权穿透显示,该公司由()间接全资持股。', '企查查APP显示,近日,中铁大桥局集团(秦皇岛)供应链管理有限公司成立,法定代表人为何士博,注册资本为100万元,经营范围包含:供应链管理服务;工程管理服务;海洋服务;海洋工程装备销售;金属结构销售等。企查查股权穿透显示,该公司由中国中铁间接全资持股。', 'https://news.10jqka.com.cn/20250714/c669607089.shtml', '港股,A股', '2025-07-14 12:35:49', ''), ('3250163', '河南发布高温红色预警 部分地区将升至40℃以上', '河南省气象台7月14日12时升级发布高温红色预警:预计7月14日下午,新乡中西部、焦作、洛阳北部、郑州、开封、商丘西部、许昌东部、周口、漯河东部、驻马店部分县(市、区)最高气温将升至40℃以上。7月15日白天,黄河以北和洛阳北部、郑州、开封、商丘西部、许昌、周口北部、漯河北部部分县(市、区)最高气温将升至40℃以上。7月16日白天,黄河以南部分县(市、区)最高气温将升至40℃以上。(央视新闻)', '河南省气象台7月14日12时升级发布高温红色预警:预计7月14日下午,新乡中西部、焦作、洛阳北部、郑州、开封、商丘西部、许昌东部、周口、漯河东部、驻马店部分县(市、区)最高气温将升至40℃以上。7月15日白天,黄河以北和洛阳北部、郑州、开封、商丘西部、许昌、周口北部、漯河北部部分县(市、区)最高气温将升至40℃以上。7月16日白天,黄河以南部分县(市、区)最高气温将升至40℃以上。(央视新闻)', 'https://news.10jqka.com.cn/20250714/c669607268.shtml', '港股,A股', '2025-07-14 12:53:40', ''), ('3250169', '平均每天10班船驶向欧美 从深圳盐田港看中国外贸“加速度”', '海关统计,今年上半年,我国货物贸易进出口总值21.79万亿元,同比增长2.9%。广东深圳()是世界最大的单体集装箱码头之一,每天都有超过4万个标准集装箱从这里发往全球,是名副其实的“世界级航运枢纽”。深圳海关数据显示,今年上半年,盐田港集装箱吞吐量超758万标箱,同比增长12.7%,实现2位数增长。不仅如此,盐田港今年还新增了11条航线,目前每周近百条航线连通全球,平均每天就有4班船驶向欧洲、6班船前往美国。可以说,深圳用稳定高效的港口体系,为外贸企业跑出“加速度”提供了坚实支撑。(央视)', '海关统计,今年上半年,我国货物贸易进出口总值21.79万亿元,同比增长2.9%。广东深圳盐田港是世界最大的单体集装箱码头之一,每天都有超过4万个标准集装箱从这里发往全球,是名副其实的“世界级航运枢纽”。深圳海关数据显示,今年上半年,盐田港集装箱吞吐量超758万标箱,同比增长12.7%,实现2位数增长。不仅如此,盐田港今年还新增了11条航线,目前每周近百条航线连通全球,平均每天就有4班船驶向欧洲、6班船前往美国。可以说,深圳用稳定高效的港口体系,为外贸企业跑出“加速度”提供了坚实支撑。(央视)', 'https://news.10jqka.com.cn/20250714/c669607289.shtml', '港股,A股', '2025-07-14 12:56:18', ''), ('3250035', '港股午评:恒生指数涨0.11%,恒生科技指数涨0.2%', '港股午间收盘,恒生指数涨0.11%,恒生科技指数涨0.2%。比特币屡创新高,港股加密货币概念股冲高,欧科云链涨超30%,雄岸科技涨超20%,新火科技控股涨超9%。', '港股午间收盘,恒生指数涨0.11%,恒生科技指数涨0.2%。比特币屡创新高,港股加密货币概念股冲高,欧科云链涨超30%,雄岸科技涨超20%,新火科技控股涨超9%。', 'https://news.10jqka.com.cn/20250714/c669606787.shtml', '港股,A股', '2025-07-14 12:01:55', '')]
24
+ async def create_pool():
25
+ """创建AsyncMy连接池"""
26
+ return await asyncmy.create_pool(
27
+ host=MYSQL_HOST,
28
+ user=MYSQL_USER,
29
+ password=MYSQL_PASSWORD,
30
+ db=MYSQL_DB,
31
+ minsize=1,
32
+ maxsize=5,
33
+ autocommit=False,
34
+ connect_timeout=10,
35
+ read_timeout=30,
36
+ charset='utf8mb4'
37
+ )
38
+
39
+
40
+ async def batch_insert(pool, chunk_size=100):
41
+ """批量插入数据"""
42
+ sql = """
43
+ INSERT INTO `articles`
44
+ (`article_id`, `title`, `digest`, `short`, `url`, `tag`, `ctime`, `source`)
45
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
46
+ """
47
+
48
+ total_items = len(value_tuples)
49
+ success_count = 0
50
+ start_time = datetime.now()
51
+
52
+ try:
53
+ async with pool.acquire() as conn:
54
+ async with conn.cursor() as cursor:
55
+ try:
56
+ affected_rows = await cursor.executemany(sql, value_tuples)
57
+ print(affected_rows)
58
+ await conn.commit()
59
+ success_count += len(value_tuples)
60
+ logger.info(f"成功插入 {len(value_tuples)} 条记录,当前总计: {success_count}/{total_items}")
61
+ except asyncmy.errors.Error as e:
62
+ await conn.rollback()
63
+ logger.error(f"批次插入失败: {e}, 失败记录: {len(value_tuples)} 条")
64
+ raise
65
+
66
+ except Exception as e:
67
+ logger.error(f"批量插入过程中发生错误: {e}")
68
+ raise
69
+ finally:
70
+ elapsed = (datetime.now() - start_time).total_seconds()
71
+ logger.info(f"批量插入完成. 成功: {success_count}, 失败: {total_items - success_count}, 耗时: {elapsed:.2f}秒")
72
+
73
+
74
+ async def main():
75
+ try:
76
+ # 创建连接池
77
+ pool = await create_pool()
78
+ logger.info("数据库连接池创建成功")
79
+
80
+ # 执行批量插入
81
+ await batch_insert(pool, chunk_size=50)
82
+
83
+ except Exception as e:
84
+ logger.error(f"主程序错误: {e}")
85
+ finally:
86
+ # 关闭连接池
87
+ if 'pool' in locals():
88
+ pool.close()
89
+ await pool.wait_closed()
90
+ logger.info("数据库连接池已关闭")
91
+
92
+
93
+ if __name__ == '__main__':
94
+ asyncio.run(main())
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/python
2
+ # -*- coding:UTF-8 -*-
3
+ """
4
+ # @Time : 2025-05-11 13:35
5
+ # @Author : oscar
6
+ # @Desc : None
7
+ """
8
+ from crawlo.items import Field
9
+ from crawlo.items.items import Item
10
+
11
+
12
+ class BauDuItem(Item):
13
+ url = Field()
14
+ title = Field()
15
+
16
+
17
+ class ArticleItem(Item):
18
+ article_id = Field()
19
+ title = Field()
20
+ digest = Field()
21
+ short = Field()
22
+ url = Field()
23
+ tag = Field()
24
+ ctime = Field()
25
+ source = Field()
26
+
27
+
28
+ class MiitDeviceItem(Item):
29
+ article_id = Field()
30
+ approval_certificate_no = Field() # 核准证编号
31
+ device_name = Field() # 设备名称
32
+ model_number = Field() # 设备型号
33
+ applicant = Field() # 申请单位
34
+ remarks = Field() # 备注
35
+ validity_period = Field() # 有效期
36
+ frequency_tolerance = Field() # 频率容限
37
+ frequency_range = Field() # 频率范围
38
+ transmission_power = Field() # 发射功率
39
+ occupied_bandwidth = Field() # 占用带宽
40
+ spurious_emission_limit = Field() # 杂散发射限制
41
+ issue_date = Field() # 发证日期
42
+ approval_code = Field() # 核准代码
43
+ cmiit_id = Field() # CMIIT ID
44
+ modulation_scheme = Field() # 调制方式
45
+ technology_module = Field() # 技术体制/功能模块
46
+ create_time = Field()