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

免費手機號歸屬地 API 大全:淘寶、騰訊、百度、有道等六大接口與 PHP 整合實戰

     編輯:PHP 相關知識

電商、物流、風控、表單驗證等場景常需即時查詢手機號歸屬地(省份、運營商)。本文匯總六大免費公開接口,對比參數、返回格式、穩定性,並提供生產級 PHP 封裝類,支援自動降級、快取與並發控制。

六大免費接口對比(2024 實測可用)

提供方請求示例參數返回格式穩定性備註
淘寶 https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13800138000 tel JSONP ⭐⭐⭐⭐⭐ 官方維護,支援 HTTPS,攜帶 t 參數防快取
騰訊財付通 https://life.tenpay.com/cgi-bin/mobile/MobileQueryAttribution.cgi?chgmobile=13800138000 chgmobile XML ⭐⭐⭐⭐ 需解析 XML,編碼 GBK
百付寶 https://www.baifubao.com/callback?cmd=1059&callback=phone&phone=13800138000 phone, callback, cmd JSONP ⭐⭐⭐ 需固定 cmd=1059
拍拍 https://virtual.paipai.com/extinfo/GetMobileProductInfo?mobile=13800138000&amount=10000&callname=cb mobile, amount, callname JSONP ⭐⭐ amount 必填但無實際意義
115 網盤 https://cz.115.com/?ct=index&ac=get_mobile_local&callback=jsonp&mobile=13800138000 mobile, callback JSONP ⭐⭐ 需 Referer,偶爾限流
有道 https://www.youdao.com/smartresult-xml/search.s?type=mobile&q=13800138000 type=mobile, q XML/JSONP ⭐⭐⭐ 支援 jsFlag=true 返回 JSONP

生產級 PHP 封裝:自動降級 + Redis 快取 + 並發鎖

<?php
declare(strict_types=1);

class MobileLocation {
    private const CACHE_TTL = 86400 * 30; // 30 天,歸屬地極少變更
    private const TIMEOUT = 3; // 秒

    private array $providers = [
        'taobao' => [
            'url' => 'https://tcc.taobao.com/cc/json/mobile_tel_segment.htm',
            'param' => 'tel',
            'parser' => 'parseTaobao',
        ],
        'tenpay' => [
            'url' => 'https://life.tenpay.com/cgi-bin/mobile/MobileQueryAttribution.cgi',
            'param' => 'chgmobile',
            'parser' => 'parseTenpay',
        ],
        'youdao' => [
            'url' => 'https://www.youdao.com/smartresult-xml/search.s',
            'param' => 'q',
            'extra' => ['type' => 'mobile', 'jsFlag' => 'true'],
            'parser' => 'parseYoudao',
        ],
    ];

    public function __construct(
        private \Redis $redis,
        private \GuzzleHttp\Client $http
    ) {}

    public function get(string $mobile): ?array {
        $mobile = $this->normalize($mobile);
        if (!$mobile) return null;

        $cacheKey = "mobile:loc:{$mobile}";
        // 1. 快取命中
        if ($cached = $this->redis->get($cacheKey)) {
            return json_decode($cached, true);
        }

        // 2. 併發鎖防止快取擊穿
        $lockKey = "lock:{$cacheKey}";
        $lock = $this->redis->set($lockKey, '1', ['nx', 'ex' => 10]);
        if (!$lock) {
            // 等待並重試快取
            usleep(200000);
            return $this->redis->get($cacheKey) ? json_decode($this->redis->get($cacheKey), true) : null;
        }

        try {
            // 3. 依序嘗試提供商
            foreach ($this->providers as $name => $cfg) {
                $data = $this->fetch($name, $cfg, $mobile);
                if ($data) {
                    $this->redis->setex($cacheKey, self::CACHE_TTL, json_encode($data));
                    return $data;
                }
            }
            return null;
        } finally {
            $this->redis->del($lockKey);
        }
    }

    private function fetch(string $name, array $cfg, string $mobile): ?array {
        $params = [$cfg['param'] => $mobile];
        if (!empty($cfg['extra'])) $params = array_merge($params, $cfg['extra']);

        try {
            $resp = $this->http->get($cfg['url'], [
                'query' => $params,
                'timeout' => self::TIMEOUT,
                'headers' => ['User-Agent' => 'MobileLocation/1.0'],
            ]);
            $body = (string)$resp->getBody();
            return $this->{$cfg['parser']}($body);
        } catch (\Throwable $e) {
            error_log("[MobileLocation] {$name} failed: {$e->getMessage()}");
            return null;
        }
    }

    // 解析器:統一返回 ['province' => '', 'carrier' => '']
    private function parseTaobao(string $body): ?array {
        // 返回格式:__GetZoneResult_ = {mts:'13800138000', province:'北京', catName:'中国移动', ...};
        if (preg_match("/province\s*:\s*'([^']+)'/", $body, $m)) {
            $province = $m[1];
        } elseif (preg_match('/"province"\s*:\s*"([^"]+)"/', $body, $m)) {
            $province = $m[1];
        } else {
            return null;
        }
        if (preg_match("/catName\s*:\s*'([^']+)'/", $body, $m)) {
            $carrier = $m[1];
        } elseif (preg_match('/"catName"\s*:\s*"([^"]+)"/', $body, $m)) {
            $carrier = $m[1];
        } else {
            $carrier = '';
        }
        return ['province' => $province, 'carrier' => $carrier];
    }

    private function parseTenpay(string $xml): ?array {
        $xml = simplexml_load_string($xml);
        if (!$xml) return null;
        return [
            'province' => (string)($xml->province ?? ''),
            'carrier'  => (string)($xml->isp ?? ''),
        ];
    }

    private function parseYoudao(string $body): ?array {
        // JSONP: fYodaoCallBack(1, {'product':'mobile','phonenum':'...','location':'北京 移动'}, "");
        if (preg_match('/location[\'"]\s*:\s*[\'"]([^\'"]+)[\'"]/', $body, $m)) {
            $parts = explode(' ', $m[1], 2);
            return [
                'province' => $parts[0] ?? '',
                'carrier'  => $parts[1] ?? '',
            ];
        }
        return null;
    }

    private function normalize(string $mobile): string {
        $mobile = preg_replace('/\D/', '', $mobile);
        return (strlen($mobile) === 11 && $mobile[0] === '1') ? $mobile : '';
    }
}

// 使用示例
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$http = new GuzzleHttp\Client();
$locator = new MobileLocation($redis, $http);

$result = $locator->get('13800138000');
var_dump($result);
// ['province' => '北京', 'carrier' => '中国移动']

關鍵工程化細節

  1. 多源降級: 依序嘗試,單點失效不影響整體可用性。
  2. Redis 快取 + 分佈式鎖: 避免熱門號碼並發回源擊穿上游。
  3. 超時控制: Guzzle timeout=3s,防止慢查詢拖垮主流程。
  4. 解析器容錯: 正則同時匹配單雙引號、JSON/JSONP 變體。
  5. HTTPS 優先: 淘寶、有道支援 HTTPS,減少鏈路劫持。
  6. 號碼歸一化: 去除非數字、校驗 11 位且以 1 開頭。

替代方案:離線資料庫

若極度追求效能與可控性,可採用「號段庫 + 定期更新」:

  • 下載工信部最新號段資料(CSV/Excel),導入 MySQL/Redis/本地陣列。
  • 查詢 O(1),零外部依賴,適合高併發核心鏈路。
  • 每月定時任務同步更新,維護成本極低。

總結

免費接口適合中低頻、非核心業務;核心鏈路建議自建離線庫。無論哪種方案,**快取、降級、超時、監控** 四件套缺一不可。本文提供的封裝類可直接納入項目,按需擴展提供商與解析器。

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