pageUrl = $pageUrl; $this->account = $account; $this->password = $password; $this->unifiedData = new UnifiedScrmData(); } /** @return array */ protected function getSpiderConfig(): array { $host = (string) parse_url($this->pageUrl, PHP_URL_HOST); return [ 'pageUrl' => $this->pageUrl, 'listApi' => self::API_LIST, 'detailApi' => self::API_DETAILS, 'listMethod' => 'POST', 'paginationMode' => self::MODE_UI, 'authActions' => [ // Element Plus 密码弹窗:仅注入可见 input ['type' => 'vue_fill', 'selector' => '.el-input__inner', 'value' => $this->password], ['type' => 'wait', 'ms' => 500], ['type' => 'vue_click', 'selector' => '.vxe-button-group .theme--primary'], ['type' => 'wait', 'ms' => 2200], ], // Whatshub 专用:Real Browser + Turnstile + Captcha API 兜底 + 会话复用 'antiBot' => [ 'enabled' => true, 'profile' => 'real', 'turnstile' => true, 'solverFallback' => true, 'sessionKey' => 'whatshub:' . $host, 'challengeTimeoutMs' => 60000, ], ]; } /** * @param array|null $listFirstPageData * @param array|null $countData */ protected function extractListTotalPages($listFirstPageData, $countData = null) { $defaultPerPage = self::DEFAULT_PER_PAGE_COUNT; $this->unifiedData->total = (int) ($listFirstPageData['data']['total'] ?? 0); if ($this->unifiedData->total <= $defaultPerPage) { return 1; } return (int) ceil($this->unifiedData->total / $defaultPerPage); } /** @return array */ protected function buildListPageParams(int $page): array { return ['pageNum' => $page, 'pageSize' => self::DEFAULT_PER_PAGE_COUNT]; } /** @return array */ protected function getUiPaginationConfig(): array { return [ 'nextBtnSelector' => '.vxe-pager--next-btn', 'waitMs' => 1500, ]; } protected function parseToUnifiedData($detailData, array $allListPagesData): UnifiedScrmData { $unifiedData = $this->unifiedData; if (is_array($detailData)) { $unifiedData->todayNewCount = (int) ($detailData['data']['dayNewFans'] ?? 0); } foreach ($allListPagesData as $pageRaw) { if (!is_array($pageRaw)) { continue; } $records = $pageRaw['data']['rows'] ?? []; if (!is_array($records)) { continue; } foreach ($records as $item) { if (!is_array($item) || empty($item['account'])) { continue; } $number = (string) $item['account']; $isOnline = isset($item['isOnline']) && (int) $item['isOnline'] === 1; $unifiedData->addNumber($number, $isOnline, (int) ($item['dayNewFans'] ?? 0)); } } $unifiedData->total = count($unifiedData->numbers); return $unifiedData; } }