首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 使用 cURL 檢測百度收錄狀態:完整實現與原理解析

     編輯:PHP 綜合知識

核心思路

百度搜索結果頁中,若頁面已被收錄,其 URL 會以高亮(<b> 標籤)形式出現。通過 cURL 獲取搜索結果頁 HTML,檢查目標 URL 是否包含在 <b> 標籤中,即可判斷收錄狀態。

完整實現代碼

<?php
/**
 * 檢測百度收錄狀態
 * @param string $url 待檢測的完整 URL(含協議)
 * @return int 1=已收錄, 0=未收錄
 */
function checkBaiduIndex(string $url): int {
    // 1. 構造搜索請求
    $searchUrl = 'https://www.baidu.com/s?wd=' . urlencode($url);
    
    // 2. cURL 獲取頁面
    $ch = curl_init($searchUrl);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
    ]);
    $html = curl_exec($ch);
    curl_close($ch);
    
    if ($html === false) {
        return 0; // 請求失敗視為未收錄
    }
    
    // 3. 提取查詢詞(去除協議、參數等干擾)
    $query = parse_url($searchUrl, PHP_URL_QUERY); // wd=xxx
    $query = urldecode(str_replace('wd=', '', $query));
    // 進一步清理:去除協議、路徑、查詢參數,只保留核心域名/路徑
    $query = preg_replace('#^https?://#', '', $query);
    $query = preg_replace('#\?.*$#', '', $query);
    $query = explode('/', $query)[0]; // 取首段
    
    // 4. 判斷是否在 <b> 標籤中高亮
    $highlighted = '<b>' . preg_quote($query, '/') . '</b>';
    return (stripos($html, $highlighted) !== false) ? 1 : 0;
}

// 測試
var_dump(checkBaiduIndex('https://www.jb51.net/')); // 1 或 0
?>

關鍵細節解析

1. User-Agent 偽裝

百度對無 UA 或異常 UA 的請求會返回驗證碼或 403,必須設置真實瀏覽器 UA。

2. 查詢詞提取邏輯

原代碼中用 parse_url 解析搜索 URL 的 query 部分,再通過字符串替換提取核心關鍵詞。改進版直接對傳入的 $url 處理,更直觀:

$core = preg_replace('#^https?://#', '', $url);
$core = explode('/', $core)[0]; // 取域名或首級路徑

3. 高亮匹配策略

百度結果頁中,收錄的 URL 關鍵詞會被 <b> 包裹。使用 stripos 大小寫不敏感查找,避免大小寫導致誤判。

4. 錯誤容錯

  • 網絡超時、DNS 失敗、SSL 驗證失敗均返回 0
  • 生產環境建議啟用 CURLOPT_SSL_VERIFYPEER => true 並配置 CA 憑證

進階:批量檢測與緩存

<?php
class BaiduIndexChecker {
    private $cacheFile;
    private $cache = [];
    private $cacheTTL = 3600; // 1 小時緩存
    
    public function __construct(string $cacheFile = __DIR__ . '/baidu_index_cache.json') {
        $this->cacheFile = $cacheFile;
        if (file_exists($cacheFile)) {
            $this->cache = json_decode(file_get_contents($cacheFile), true) ?? [];
        }
    }
    
    public function check(string $url): int {
        $key = md5($url);
        $now = time();
        
        // 緩存命中
        if (isset($this->cache[$key]) && $now - $this->cache[$key]['time'] < $this->cacheTTL) {
            return $this->cache[$key]['status'];
        }
        
        // 實時檢測
        $status = $this->requestBaidu($url);
        
        // 更新緩存
        $this->cache[$key] = ['status' => $status, 'time' => $now];
        $this->saveCache();
        
        return $status;
    }
    
    private function requestBaidu(string $url): int {
        $ch = curl_init('https://www.baidu.com/s?wd=' . urlencode($url));
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            CURLOPT_TIMEOUT        => 8,
            CURLOPT_SSL_VERIFYPEER => false,
        ]);
        $html = curl_exec($ch);
        curl_close($ch);
        
        if ($html === false) return 0;
        
        $core = preg_replace('#^https?://#', '', $url);
        $core = explode('/', $core)[0];
        return (stripos($html, '<b>' . $core . '</b>') !== false) ? 1 : 0;
    }
    
    private function saveCache(): void {
        file_put_contents($this->cacheFile, json_encode($this->cache), LOCK_EX);
    }
}

// 使用
$checker = new BaiduIndexChecker();
$urls = [
    'https://www.jb51.net/',
    'https://www.php.net/',
    'https://example.com/not-exist-page',
];
foreach ($urls as $url) {
    echo $url . ' => ' . ($checker->check($url) ? '✅ 已收錄' : '❌ 未收錄') . PHP_EOL;
}
?>

注意事項與法律合規

  • 頻率控制:單 IP 短時間大量查詢會觸發百度驗證碼,建議間隔 ≥ 3 秒,或使用代理池輪換
  • 僅供參考:百度前端展示邏輯可能調整,此方法不保證 100% 準確,權威數據請使用百度站長平台 API
  • 遵守 robots.txt:批量查詢屬於自動化訪問,請確認目標站點允許

替代方案:百度站長平台 API

若有站長平台權限,可調用 https://zhanzhang.baidu.com/api/indexsite 等官方接口,準確率 100%、無頻率限制風險,為生產環境首選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved