🎉 主要更新:
后端:
- 全新华为应用市场爬虫系统
- 三表分离数据库设计 (app_info, app_metrics, app_rating)
- 完整的API接口 (搜索、分类、热门、上新等)
- 元服务自动识别和分类
- 智能Token管理和数据处理
- 修复热门应用重复显示问题
前端:
- 全新首页设计 (今日上架、热门应用)
- 应用页面 (彩色分类磁贴、智能图标匹配)
- 今日上新页面 (日期切换)
- 热门应用页面 (卡片布局)
- 应用详情页面 (完整信息展示)
- Apple风格搜索栏
- Footer组件
- 底部导航栏优化 (4个导航项)
- 骨架屏加载效果
- FontAwesome图标集成
UI/UX:
- 统一浅色背景 (#F5F5F7)
- 流畅的过渡动画
- 响应式设计
- 毛玻璃效果
文档:
- CHANGELOG.md - 完整更新日志
- QUICKSTART.md - 快速开始
- 多个技术文档和使用指南
版本: v2.0.0
197 lines
4.8 KiB
Markdown
197 lines
4.8 KiB
Markdown
# 华为应用市场爬虫
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 进入爬虫目录
|
||
cd backend/app/crawler
|
||
|
||
# 爬取所有962个应用(默认50并发)
|
||
python3 crawl.py
|
||
|
||
# 或者只爬取前10个应用(测试)
|
||
python3 crawl.py --limit 10
|
||
```
|
||
|
||
脚本会自动检查并创建数据库表(如果不存在)
|
||
|
||
## 使用说明
|
||
|
||
### 命令参数
|
||
|
||
```bash
|
||
python3 crawl.py [选项]
|
||
|
||
选项:
|
||
--limit N 只爬取前N个应用(默认爬取所有962个)
|
||
--batch N 并发数量(默认50)
|
||
--skip-init 跳过数据库初始化检查
|
||
-h, --help 显示帮助信息
|
||
```
|
||
|
||
### 使用示例
|
||
|
||
```bash
|
||
# 爬取所有应用(50并发)
|
||
python3 crawl.py
|
||
|
||
# 爬取前10个应用
|
||
python3 crawl.py --limit 10
|
||
|
||
# 使用100并发爬取
|
||
python3 crawl.py --batch 100
|
||
|
||
# 爬取100个应用,使用20并发
|
||
python3 crawl.py --limit 100 --batch 20
|
||
|
||
# 跳过数据库检查直接爬取
|
||
python3 crawl.py --skip-init
|
||
```
|
||
|
||
## 性能对比
|
||
|
||
| 并发数 | 爬取100个应用 | 爬取962个应用 |
|
||
|--------|--------------|--------------|
|
||
| 5 | ~10秒 | ~2分钟 |
|
||
| 10 | ~5秒 | ~1分钟 |
|
||
| 50 | ~2秒 | ~20秒 |
|
||
| 100 | ~1秒 | ~10秒 |
|
||
|
||
## 文件说明
|
||
|
||
- `crawl.py` - 爬虫命令行入口(主程序)
|
||
- `guess.py` - 应用ID列表(962个已知的鸿蒙应用ID)
|
||
- `app_ids.py` - ID加载器(从guess.py加载ID)
|
||
- `crawler.py` - 爬虫核心类
|
||
- `huawei_api.py` - 华为API封装
|
||
- `token_manager.py` - Token自动管理
|
||
- `data_processor.py` - 数据处理和保存
|
||
|
||
## 工作流程
|
||
|
||
1. **检查数据库**:自动检查表是否存在,不存在则创建
|
||
2. **加载ID列表**:从 `guess.py` 加载962个应用ID
|
||
3. **并发爬取**:
|
||
- 分批并发获取应用信息
|
||
- 获取评分数据
|
||
- 保存到数据库(智能去重)
|
||
4. **显示进度**:实时显示爬取进度和状态
|
||
|
||
## 输出说明
|
||
|
||
```
|
||
[1/962] C6917559067092904725 ✓ 突击射击 → 新应用, 新指标, 新评分
|
||
```
|
||
|
||
- `[1/962]`: 当前进度
|
||
- `C6917559067092904725`: 应用ID
|
||
- `✓ 突击射击`: 成功获取应用信息
|
||
- `→ 新应用, 新指标, 新评分`: 保存状态
|
||
- `新应用`: 首次保存该应用的基本信息
|
||
- `新指标`: 保存了新的版本指标记录
|
||
- `新评分`: 保存了新的评分记录
|
||
- `无更新`: 数据无变化,未保存新记录
|
||
|
||
## 数据存储
|
||
|
||
爬取的数据保存在三张表中:
|
||
|
||
### app_info(应用基本信息)
|
||
- 主键:app_id
|
||
- 唯一索引:pkg_name
|
||
- 包含:名称、开发者、分类、图标、描述、设备支持、SDK信息等
|
||
|
||
### app_metrics(应用指标历史)
|
||
- 自增主键:id
|
||
- 外键:app_id, pkg_name
|
||
- 包含:版本号、大小、下载量、发布时间
|
||
- 每次版本或下载量变化时新增一条记录
|
||
|
||
### app_rating(应用评分历史)
|
||
- 自增主键:id
|
||
- 外键:app_id, pkg_name
|
||
- 包含:平均评分、各星级数量、总评分数
|
||
- 每次评分变化时新增一条记录
|
||
|
||
## 新增字段
|
||
|
||
### 设备支持
|
||
- `main_device_codes`: 支持的设备列表
|
||
- 0: 手机
|
||
- 1: 平板
|
||
- 2: 智慧屏
|
||
- 3: 手表
|
||
- 4: 车机
|
||
- 5: PC
|
||
|
||
### SDK信息
|
||
- `target_sdk`: 目标SDK版本
|
||
- `min_sdk`: 最低SDK版本
|
||
- `compile_sdk_version`: 编译SDK版本
|
||
- `min_hmos_api_level`: 最低HarmonyOS API级别
|
||
- `api_release_type`: API发布类型
|
||
|
||
### 其他信息
|
||
- `dev_id`: 开发者ID
|
||
- `supplier`: 供应商
|
||
- `kind_id`: 分类ID
|
||
- `tag_name`: 标签名称
|
||
- `price`: 价格
|
||
- `ctype`: 内容类型
|
||
- `app_level`: 应用级别
|
||
- `packing_type`: 打包类型
|
||
|
||
## 注意事项
|
||
|
||
1. **Token管理**:Token会自动刷新,有效期约1小时
|
||
2. **爬取速度**:并发数越高速度越快,但建议不超过100
|
||
3. **网络稳定性**:高并发对网络要求较高
|
||
4. **数据库连接**:确保数据库支持足够的并发连接
|
||
5. **重复运行**:可以重复运行,只会保存有变化的数据
|
||
|
||
## 故障排查
|
||
|
||
### 数据库连接失败
|
||
```
|
||
✗ 数据库检查失败: (pymysql.err.OperationalError)
|
||
```
|
||
**解决方案**:
|
||
- 检查 `backend/.env` 文件中的数据库配置
|
||
- 确认数据库服务器可访问
|
||
|
||
### Token刷新失败
|
||
```
|
||
✗ Token刷新失败
|
||
```
|
||
**解决方案**:
|
||
- 检查网络连接
|
||
- 等待片刻后重试
|
||
|
||
### 应用爬取失败
|
||
```
|
||
✗ 跳过(安卓应用)
|
||
```
|
||
**说明**:这是正常的,表示该ID对应的是安卓应用,不是鸿蒙应用
|
||
|
||
### 并发过高导致失败
|
||
**解决方案**:降低并发数
|
||
```bash
|
||
python3 crawl.py --batch 20
|
||
```
|
||
|
||
## 编程方式使用
|
||
|
||
```python
|
||
import asyncio
|
||
from app.crawler import HuaweiCrawler
|
||
|
||
async def main():
|
||
# 使用上下文管理器
|
||
async with HuaweiCrawler() as crawler:
|
||
# 爬取前10个应用,使用50并发
|
||
success, failed = await crawler.crawl_by_ids(limit=10, batch_size=50)
|
||
print(f"成功: {success}, 失败: {failed}")
|
||
|
||
asyncio.run(main())
|
||
```
|