|
|
@@ -7,13 +7,17 @@ import re
|
|
|
import time
|
|
|
from datetime import datetime
|
|
|
|
|
|
+import requests
|
|
|
+
|
|
|
from commons.Logger import get_spider_logger
|
|
|
-from commons.scheduler import CrawlerScheduler
|
|
|
from commons.feishu_webhook import send_text, send_error_card
|
|
|
from spiders.yaoex.yaoex_crawl import (
|
|
|
YaoexCrawler,
|
|
|
PLATFORM_ID,
|
|
|
YYC_DEVICE_ID,
|
|
|
+ TASK_PULL_URL,
|
|
|
+ TASK_HEARTBEAT_URL,
|
|
|
+ TASK_API_TOKEN,
|
|
|
)
|
|
|
from spiders.yaoex.yaoex_snapshot_crawl import YaoexSnapshotCrawl
|
|
|
|
|
|
@@ -24,6 +28,42 @@ IDLE_SECONDS_MIN = 180
|
|
|
IDLE_SECONDS_MAX = 300
|
|
|
|
|
|
|
|
|
+def pull_task():
|
|
|
+ """从内部调度 API 拉取任务"""
|
|
|
+ headers = {'X-Crawler-Token': TASK_API_TOKEN}
|
|
|
+ params = {'platform': PLATFORM_ID, 'username': YYC_DEVICE_ID}
|
|
|
+ try:
|
|
|
+ response = requests.get(TASK_PULL_URL, params=params, headers=headers, timeout=15)
|
|
|
+ result = response.json()
|
|
|
+ logger.info("拉取任务 API 返回: %s", result)
|
|
|
+ if result.get('code') == 'success':
|
|
|
+ task = result.get('data', {}).get('task') or {}
|
|
|
+ if task and task.get("id"):
|
|
|
+ logger.info("拉取任务成功 platform=%s task_id=%s", PLATFORM_ID, task.get("id"))
|
|
|
+ return task
|
|
|
+ else:
|
|
|
+ logger.info("拉取任务成功但无有效任务(task=%s),视为暂无任务", task)
|
|
|
+ return {}
|
|
|
+ else:
|
|
|
+ logger.warning("拉取任务 API 返回非 success: code=%s, msg=%s",
|
|
|
+ result.get('code'), result.get('msg'))
|
|
|
+ return {}
|
|
|
+ except Exception as e:
|
|
|
+ logger.error("拉取任务 API 请求失败: %s", e)
|
|
|
+ return {}
|
|
|
+
|
|
|
+
|
|
|
+def send_heartbeat():
|
|
|
+ """向调度 API 上报心跳,告知服务器爬虫在线"""
|
|
|
+ headers = {'X-Crawler-Token': TASK_API_TOKEN}
|
|
|
+ payload = {"platform": str(PLATFORM_ID), "username": YYC_DEVICE_ID}
|
|
|
+ try:
|
|
|
+ resp = requests.post(TASK_HEARTBEAT_URL, json=payload, headers=headers, timeout=10)
|
|
|
+ logger.debug("心跳上报: HTTP %s, %s", resp.status_code, resp.text[:200])
|
|
|
+ except Exception as e:
|
|
|
+ logger.warning("心跳上报失败: %s", e)
|
|
|
+
|
|
|
+
|
|
|
def notify_result(task, crawl_count, success):
|
|
|
"""发送飞书通知"""
|
|
|
try:
|
|
|
@@ -50,16 +90,14 @@ def notify_result(task, crawl_count, success):
|
|
|
|
|
|
def main_loop():
|
|
|
"""循环拉取任务并执行采集"""
|
|
|
- scheduler = CrawlerScheduler(YYC_DEVICE_ID, str(PLATFORM_ID))
|
|
|
idle_seconds = random.randint(IDLE_SECONDS_MIN, IDLE_SECONDS_MAX)
|
|
|
logger.info("壹药城采集启动,每轮间隔 %s 秒", idle_seconds)
|
|
|
|
|
|
while True:
|
|
|
try:
|
|
|
- # 先同步心跳,确保服务器登记后再拉任务
|
|
|
- scheduler.heartbeat_once()
|
|
|
- scheduler.start()
|
|
|
- task = scheduler.get_task() or {}
|
|
|
+ # 先上报心跳,告诉服务器爬虫在线
|
|
|
+ send_heartbeat()
|
|
|
+ task = pull_task()
|
|
|
if not task:
|
|
|
logger.info("%s 暂无任务,等待 %s 秒后重试", PLATFORM_NAME, idle_seconds)
|
|
|
time.sleep(idle_seconds)
|