'commit'
This commit is contained in:
@@ -30,29 +30,15 @@ logger = logging.getLogger("AiTeJiYiChongCrawler")
|
||||
|
||||
async def is_already_crawled(redis_kit, station_name):
|
||||
"""
|
||||
检查场站是否已经爬取过,支持前缀模糊匹配处理截断名称
|
||||
检查场站是否已经爬取过,仅按名称去重
|
||||
"""
|
||||
cleaned_name = Kit.clean_station_name(station_name)
|
||||
if not cleaned_name:
|
||||
return False
|
||||
|
||||
# 1. 检查精确匹配
|
||||
redis_key = f"crawled:aite:{cleaned_name}"
|
||||
if await redis_kit.get_data(redis_key):
|
||||
return True
|
||||
|
||||
# 2. 如果名称被截断(原名包含 . ),尝试前缀匹配
|
||||
# 逻辑:在 Redis 中查找是否有以当前清理后的名称开头的已完成场站
|
||||
# 为了效率,我们配合 Redis 的 keys 模式(小规模数据下可用)
|
||||
if ".." in station_name or station_name.endswith("."):
|
||||
# 获取所有已爬取的 key 进行内存前缀比对,或者利用 Redis 模糊查询
|
||||
# 这里采用一种更高效的方式:在详情页保存时,额外保存一个前缀索引
|
||||
prefix_key = f"crawled:aite:prefix:{cleaned_name[:6]}" # 取前6位作为索引前缀
|
||||
stored_names = await redis_kit.get_data(prefix_key)
|
||||
if stored_names and isinstance(stored_names, list):
|
||||
for full_name in stored_names:
|
||||
if full_name.startswith(cleaned_name):
|
||||
return True
|
||||
return False
|
||||
|
||||
async def get_station_list(d, service, max_scrolls=MAX_SCROLLS):
|
||||
@@ -190,16 +176,9 @@ async def get_station_list(d, service, max_scrolls=MAX_SCROLLS):
|
||||
d.press("back")
|
||||
await asyncio.sleep(0.8)
|
||||
|
||||
# 记录 Redis (保存全名并建立前缀索引)
|
||||
# 记录 Redis (仅按名称去重,不再使用前缀索引)
|
||||
full_name_key = f"crawled:aite:{Kit.clean_station_name(station_name)}"
|
||||
await redis_kit.set_data(full_name_key, "1", expire=REDIS_STATION_EXPIRE)
|
||||
|
||||
# 建立前缀索引 (取前6位,方便模糊查找)
|
||||
prefix_idx_key = f"crawled:aite:prefix:{Kit.clean_station_name(station_name)[:6]}"
|
||||
existing_names = await redis_kit.get_data(prefix_idx_key) or []
|
||||
if station_name not in existing_names:
|
||||
existing_names.append(station_name)
|
||||
await redis_kit.set_data(prefix_idx_key, existing_names, expire=REDIS_STATION_EXPIRE)
|
||||
|
||||
# 在每一页结束时,清理已完成的任务,防止内存堆积
|
||||
done_tasks = [t for t in background_tasks if t.done()]
|
||||
|
||||
@@ -44,9 +44,14 @@
|
||||
2. **用户体验**: UI 操作(点击、滑动、返回)是连续的,不会因为网络请求波动而卡顿。
|
||||
- **任务追踪**: 在 `Crawler.py` 中维护 `background_tasks` 列表,在每页结束时清理已完成任务,并在整个爬取结束时使用 `asyncio.gather` 等待残余任务。
|
||||
|
||||
### 3.2 智能去重机制
|
||||
- **Redis 模糊匹配**: 针对小程序中场站名称可能被省略号截断(如“万达茂...”)的情况,不仅存储全名,还存储场站名称的前 6 位作为前缀索引。
|
||||
- **逻辑**: 先查全名,再查前缀索引。如果前缀匹配成功,则视为已爬取,跳过重复工作。
|
||||
### 3.2 场站去重策略
|
||||
- **按名称去重**: 仅依据列表显示的场站名称进行去重,不再使用前缀或模糊匹配。
|
||||
- **处理规则**:
|
||||
- 名称先经 `clean_station_name` 去掉尾部省略号与空格,例如 `AAABBB...` → `AAABBB`;
|
||||
- 首次遇到该名称时处理并写入 Redis 键 `crawled:aite:{name}`;
|
||||
- 后续再遇到同名(包括省略号截断的同名)直接跳过,不再点击进入详情页。
|
||||
- **设计原因**: 逻辑直白、符合业务预期,降低模糊匹配带来的误判风险。
|
||||
- **一致性说明**: 新电途项目采用同样的按名称去重策略以保持跨项目行为一致。
|
||||
|
||||
### 3.3 坐标系转换
|
||||
- **VL 坐标**: 0-1000 的归一化坐标。
|
||||
|
||||
Reference in New Issue
Block a user