修复A2C工单蜘蛛

This commit is contained in:
root
2026-07-01 01:26:27 +08:00
parent 9f2e904fab
commit 54c13c54ef
22 changed files with 1614 additions and 272 deletions
@@ -25,43 +25,46 @@ class AntiBotConfigBuilder
return null;
}
$host = (string) parse_url($pageUrl, PHP_URL_HOST);
if ($host === '') {
$sessionHost = self::resolveSessionHost($ticketType, $pageUrl);
if ($sessionHost === '') {
return null;
}
$sessionKey = $ticketType . ':' . $host;
$sessionKey = $ticketType . ':' . $sessionHost;
$ttlMinutes = self::getSessionTtlMinutes();
return [
'enabled' => true,
'profile' => 'real',
'turnstile' => true,
'solverFallback' => true,
'turnstile' => self::defaultTurnstile($ticketType),
'solverFallback' => self::defaultSolverFallback($ticketType),
'cfClearanceRequired'=> self::defaultCfClearanceRequired($ticketType),
'sessionKey' => $sessionKey,
'challengeTimeoutMs' => 60000,
'sessionTtlMinutes' => $ttlMinutes,
'businessHostHint' => self::defaultBusinessHostHint($ticketType, $sessionHost),
] + self::postCfReadyExtras($ticketType);
}
/**
* 按工单类型附加 CF 过盾后的业务页就绪等待(仅 Whatshub 等需要的类型)
*
* @return array<string, mixed>
* 会话域:A2C 短链(yyk.ink)仍用业务域 user.a2c.chat 复用 Real Browser 会话
*/
private static function postCfReadyExtras(string $ticketType): array
public static function resolveSessionHost(string $ticketType, string $pageUrl): string
{
if ($ticketType !== 'whatshub') {
return [];
$host = strtolower(trim((string) parse_url($pageUrl, PHP_URL_HOST)));
if ($host === '') {
return '';
}
return [
'postCfReadyUrlContains' => 'work-order-sharing',
'postCfReadySelector' => '.el-input__inner',
'postCfReadyTimeoutMs' => 30000,
'postCfSettleMs' => 500,
'postCfSpaWaitMs' => 4000,
];
if ($ticketType === 'a2c') {
if (strpos($host, 'a2c.chat') !== false) {
return $host;
}
return 'user.a2c.chat';
}
return $host;
}
/**
@@ -69,7 +72,8 @@ class AntiBotConfigBuilder
*/
public static function resolveSessionKey(string $ticketType, string $pageUrl): string
{
$host = (string) parse_url($pageUrl, PHP_URL_HOST);
$host = self::resolveSessionHost($ticketType, $pageUrl);
return $ticketType . ':' . ($host !== '' ? $host : 'unknown');
}
@@ -101,4 +105,66 @@ class AntiBotConfigBuilder
$minutes = (int) Config::get('site.split_scrm_session_ttl_minutes');
return $minutes > 0 ? $minutes : 120;
}
/**
* 按工单类型附加 CF 过盾后的业务页就绪等待
*
* @return array<string, mixed>
*/
private static function postCfReadyExtras(string $ticketType): array
{
if ($ticketType === 'whatshub') {
return [
'postCfReadyUrlContains' => 'work-order-sharing',
'postCfReadySelector' => '.el-input__inner',
'postCfReadyTimeoutMs' => 30000,
'postCfSettleMs' => 500,
'postCfSpaWaitMs' => 4000,
];
}
if ($ticketType === 'a2c') {
return [
'postCfReadyUrlContains' => '/visitors/counter/share',
'postCfReadySelector' => '.btn-next',
'postCfReadyTimeoutMs' => 30000,
'postCfSettleMs' => 500,
'postCfSpaWaitMs' => 4000,
];
}
return [];
}
private static function defaultTurnstile(string $ticketType): bool
{
return true;
}
private static function defaultSolverFallback(string $ticketType): bool
{
if ($ticketType === 'a2c') {
return false;
}
return true;
}
private static function defaultCfClearanceRequired(string $ticketType): bool
{
if ($ticketType === 'a2c') {
return false;
}
return true;
}
private static function defaultBusinessHostHint(string $ticketType, string $sessionHost): string
{
if ($ticketType === 'a2c') {
return $sessionHost;
}
return '';
}
}
@@ -9,7 +9,9 @@ use app\common\library\scrm\AntiBotConfigBuilder;
use app\common\library\scrm\UnifiedScrmData;
/**
* A2C 云控蜘蛛(Real Browser + Turnstile 过盾 + UI 翻页)
* A2C 云控蜘蛛(Real Browser 打开分享页 + 拦截加密 API + UI 翻页)
*
* 业务域 user.a2c.chat 无需 cf_clearance;短链 yyk.ink 仍由浏览器 follow 跳转。
*/
class A2cSpider extends AbstractScrmSpider
{