chenjunhao 2 tygodni temu
rodzic
commit
cff295b883

+ 6 - 3
spiders/yaoex/yaoex_crawl.py

@@ -16,10 +16,10 @@ TOKEN = "Sm45MzRmREtiaStVTnJORXEySHhYYzNwUmQ2RUprWXlwelRDem4wV2RZUCtUUU5jMGVCVTR
 
 # 平台常量(API 调度用)
 PLATFORM_ID = 6
-YYC_DEVICE_ID = "18193030281"
+YYC_DEVICE_ID = "181930302811"
 
 HEARTBEAT_INTERVAL_SECONDS = 60
-TASK_API_BASE = "http://120.24.26.108:8082/api/collect_task"
+TASK_API_BASE = "http://pricesys2.kailin.com.cn:8083/api/collect_task"
 TASK_API_TOKEN = "zhijiayun_crawler_2026"
 TASK_PULL_URL = TASK_API_BASE + "/pull"
 TASK_HEARTBEAT_URL = TASK_API_BASE + "/heartbeat"
@@ -129,8 +129,11 @@ class YaoexCrawler:
             "current_page": page_no,
             "total_pages": total_pages if total_pages > 0 else page_no,
             "crawled_count": real_count,
-            "is_finished": 1 if success else 0,
+            "is_finished": 1,  # 到了 _report_end 必然已经跑完了
         }
+        if not success:
+            payload["exception_type"] = 5
+            payload["remark"] = "采集异常或API请求失败"
         logger.info("上报结束 task_id=%s payload=%s", self.task_id, payload)
         self._send_report(payload, "结束上报(is_finished=1)")
 

+ 5 - 2
spiders/yaoex/yaoex_snapshot_crawl.py

@@ -24,7 +24,7 @@ logger = get_spider_logger("yaoex_snapshot")
 # 平台常量(API 调度用)
 PLATFORM_ID = 6
 HEARTBEAT_INTERVAL_SECONDS = 60
-TASK_API_BASE = "http://120.24.26.108:8082/api/collect_task"
+TASK_API_BASE = "http://pricesys2.kailin.com.cn:8083/api/collect_task"
 TASK_API_TOKEN = "zhijiayun_crawler_2026"
 TASK_REPORT_URL = TASK_API_BASE + "/report"
 
@@ -169,8 +169,11 @@ class YaoexSnapshotCrawl:
             "current_page": page_no,
             "total_pages": total_pages if total_pages > 0 else page_no,
             "crawled_count": real_count,
-            "is_finished": 1 if success else 0,
+            "is_finished": 1,  # 到了 _report_end 必然已经跑完了
         }
+        if not success:
+            payload["exception_type"] = 5
+            payload["remark"] = "采集异常或API请求失败"
         logger.info("上报结束 task_id=%s payload=%s", self.task_id, payload)
         self._send_report(payload, "结束上报(is_finished=1)")
 

+ 25 - 67
spiders/ybm/ybm_crawl.py

@@ -13,6 +13,7 @@ import re
 import threading
 import time
 import traceback
+import urllib.parse
 from datetime import datetime
 from io import BytesIO
 
@@ -42,7 +43,7 @@ PLATFORM_ID = 9
 YBM_DEVICE_ID = "18008650300"
 
 # API(内部调度系统)
-TASK_API_BASE = "http://120.24.26.108:8082/api/collect_task"
+TASK_API_BASE = "http://pricesys2.kailin.com.cn:8083/api/collect_task"
 TASK_API_TOKEN = "zhijiayun_crawler_2026"
 
 TASK_PULL_URL = TASK_API_BASE + "/pull"
@@ -89,6 +90,7 @@ LOGIN_VALIDATE_URL = "https://www.ybm100.com/new/"
 USERNAME = "18008650300"
 PASSWORD = "12345678"
 TARGET_LOGIN_URL = "https://www.ybm100.com/new/login"
+HOME_URL = "https://www.ybm100.com/new/"
 
 # 选择器
 USERNAME_SELECTOR = "input[placeholder*=请输入账号]"
@@ -377,7 +379,7 @@ def get_current_time():
 
 def random_delay(min_seconds, max_seconds):
     delay = random.uniform(min_seconds, max_seconds)
-    time.sleep(delay)
+    time.sleep(1)
     return delay
 
 
@@ -431,11 +433,6 @@ def slow_scroll_400px(page, scroll_distance1=400):
         return False
 
 
-def type_slow(locator, text: str, min_delay=0.06, max_delay=0.18):
-    for ch in text:
-        locator.type(ch, delay=int(random.uniform(min_delay, max_delay) * 1000))
-
-
 def kill_masks(page):
     page.evaluate(r"""
     () => {
@@ -909,68 +906,21 @@ class YbmCrawler:
 
     # ---------- search ----------
 
-    @staticmethod
-    def _pick_search_input(page):
-        inputs = page.locator(SEARCH_INPUT_SELECTOR)
-        cnt = inputs.count()
-        for i in range(min(cnt, 2)):
-            candidate = inputs.nth(i)
-            try:
-                candidate.wait_for(state="visible", timeout=1500)
-                if candidate.is_enabled():
-                    return candidate
-            except PlaywrightTimeoutError:
-                continue
-        candidate = page.locator(f"{SEARCH_INPUT_SELECTOR}:visible").first
-        candidate.wait_for(state="visible", timeout=ELEMENT_TIMEOUT)
-        return candidate
-
-    def _search_operation(self, page, keyword, is_first_search=True):
+    def _search_operation(self, page, keyword):
+        """直接拼搜索结果页 URL 跳转,不再操作输入框"""
         try:
-            search_locator = self._pick_search_input(page)
-            search_locator.wait_for(timeout=ELEMENT_TIMEOUT)
-            search_locator.click(force=True)
-            search_locator.fill("")
-            page.keyboard.down("Control")
-            page.keyboard.press("a")
-            page.keyboard.up("Control")
-            page.keyboard.press("Backspace")
-            type_slow(search_locator, keyword, min_delay=0.06, max_delay=0.18)
-            logger.info(f"📝 已输入搜索关键词:{keyword}")
-            btn = page.locator(SEARCH_BTN_SELECTOR)
-            btn.wait_for(state="visible", timeout=SEARCH_BTN_TIMEOUT)
-            page.wait_for_timeout(3000)
-            detail_page = page
-            if is_first_search:
-                try:
-                    with page.context.expect_page(timeout=60000) as new_page_info:
-                        btn.click()
-                    detail_page = new_page_info.value
-                    detail_page.wait_for_load_state("networkidle", timeout=20000)
-                except PlaywrightTimeoutError:
-                    logger.warning(f"{get_current_time()}   未检测到新标签页")
-                    return None, False
-                except Exception as e:
-                    logger.warning(f"{get_current_time()}   等待新标签页异常:{e}")
-                    return None, False
-            else:
-                btn.click()
-                page.wait_for_load_state("networkidle", timeout=20000)
-                detail_page = page
-                logger.info("✅ 后续搜索:已在原页面完成跳转加载")
-            test_btn = detail_page.locator("div[data-v-c65c36bc].first-time-highlight-message-btn button")
-            if test_btn.count() > 0:
-                test_btn.wait_for(state="attached", timeout=5000)
-                test_btn.click()
-            force_close_popup(detail_page)
-            kill_masks(detail_page)
+            encoded = urllib.parse.quote(keyword)
+            search_url = f"https://www.ybm100.com/new/base/search?keyword={encoded}#/bigSearch/index"
+            logger.info(f"跳转搜索页: {search_url}")
+            page.goto(search_url, timeout=20000)
+            page.wait_for_load_state("networkidle")
+            time.sleep(1)
+            force_close_popup(page)
+            kill_masks(page)
             logger.info("✅ 已触发搜索")
-            return detail_page, True
-        except PlaywrightTimeoutError as e:
-            logger.error(f" 搜索失败:元素定位超时 - {str(e)}")
-            return None, False
+            return page, True
         except Exception as e:
-            logger.error(f" 搜索异常:{str(e)}")
+            logger.error(f"搜索失败: {e}")
             return None, False
 
     # ---------- pagination ----------
@@ -1570,12 +1520,20 @@ class YbmCrawler:
                     save_cookies(context)
                     logger.info(" 登录并保存Cookie成功!")
 
+                # 确保回到首页(登录后可能跳到了其他页面)
+                page.goto(HOME_URL, timeout=15000)
+                page.wait_for_load_state("networkidle")
+                time.sleep(1)
+                popup_guard(page, "after_login")
+                force_close_popup(page)
+                kill_masks(page)
+
                 # 启动心跳守护线程(CrawlerScheduler)
                 self.scheduler.start()
 
                 # 搜索
                 popup_guard(page, "before_search")
-                store_page, search_success = self._search_operation(page, self.keyword, is_first_search=True)
+                store_page, search_success = self._search_operation(page, self.keyword)
                 if store_page:
                     popup_guard(store_page, "after_search")