【有奖征文】用"云API"和PHP写一个查找域名是否可注册的API

初衷

想对接企业微信,或者做一个简单的HTML单页,比起开官网和小程序查快多了。

在批量查询时,可以直接通过Python调用,比起官网的批量查询要灵活得多(官网的还要先用Python生成列表再复制,而且一次查太多网页还容易出问题)。

PHP部署方便,而且腾讯云云API调用有每秒频次限制,不需要多快,很适用。

比起每个应用独自调用腾讯云API去折腾SDK或者签名流程,套一层后只需传入域名即可查询,显然要方便很多。

申请腾讯云API密钥

申请链接:https://console.cloud.tencent.com/cam/capi

企业微信截图_16624624719188.png

代码

<?php
    // 请求外部资源
    // 参数:$url,字符串。$post,array。$httpheader,字符数组。
	function getHttpResponse_h($url, $post = false,$httpheader, $timeout = 10){
	   // 要先用json_encode()处理,不然就是表单而不是json数据了
	   // 传入的数据里要带上Content-Type,标明是application/json
	    $po = json_encode($post);
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 		$httpheader[] = "Accept: */*";
// 		$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
// 		$httpheader[] = "Connection: close";
		
		curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		if($post){
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $po);
		}
		$response = curl_exec($ch);
		curl_close($ch);
		return $response;
	}
if((!isset($_GET['domain'])or($_GET['domain'] == ""))){
	echo "无参数";
	exit;
}	
$domainname = $_GET['domain'];

$secretId = "填写自己的";
$secretKey = "填写自己的";
$host = "domain.tencentcloudapi.com";
$service = "domain";
$version = "2018-08-08";
$action = "CheckDomain";
$region = "ap-guangzhou";
$timestamp = time();
// $timestamp = 1662042540;
$algorithm = "TC3-HMAC-SHA256";

// step 1: build canonical request string
$httpRequestMethod = "POST";
$canonicalUri = "/";
$canonicalQueryString = "";
$canonicalHeaders = "content-type:application/json"."\\n"."host:".$host."\\n";
$signedHeaders = "content-type;host";
$payload = '{"DomainName":"'.$domainname.'"}';
$hashedRequestPayload = hash("SHA256", $payload);
$canonicalRequest = $httpRequestMethod."\\n"
    .$canonicalUri."\\n"
    .$canonicalQueryString."\\n"
    .$canonicalHeaders."\\n"
    .$signedHeaders."\\n"
    .$hashedRequestPayload;
// echo $canonicalRequest.PHP_EOL;
// echo "<br><br>";

// step 2: build string to sign
$date = gmdate("Y-m-d", $timestamp);
$credentialScope = $date."/".$service."/tc3_request";
$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
$stringToSign = $algorithm."\\n"
    .$timestamp."\\n"
    .$credentialScope."\\n"
    .$hashedCanonicalRequest;
// echo $stringToSign.PHP_EOL;
// echo "<br><br>";

// step 3: sign string
$secretDate = hash_hmac("SHA256", $date, "TC3".$secretKey, true);
$secretService = hash_hmac("SHA256", $service, $secretDate, true);
$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
// echo $signature.PHP_EOL;
// echo "<br><br>";

// step 4: build authorization
$authorization = $algorithm
    ." Credential=".$secretId."/".$credentialScope
    .", SignedHeaders=content-type;host, Signature=".$signature;
// echo $authorization.PHP_EOL;
// echo "<br><br>";

$curl = "curl -X POST https://".$host
    .'<br>{"Authorization": "'.$authorization.'",<br>'
    .'"Content-Type": "application/json",<br>'
    .'"Host": "'.$host.'",<br>'
    .'"X-TC-Action": "'.$action.'",<br>'
    .'"X-TC-Timestamp": "'.$timestamp.'",<br>'
    .'"X-TC-Version": "'.$version.'",<br>'
    .'"X-TC-Region": "'.$region.'"}<br>'
    ." -d '".$payload."'";
// echo $curl.PHP_EOL;

$he = ['Authorization: '.$authorization,
    'Content-Type: application/json',
    'Host: '.$host,
    'X-TC-Action: '.$action,
    'X-TC-Timestamp: '.$timestamp,
    'X-TC-Version: '.$version,
    'X-TC-Region: '.$region];
    
$post_data = array("DomainName" => $domainname);
        
        $output = getHttpResponse_h($url = "https://".$host,$post = $post_data,$httpheader = $he);
// echo($output);

$outjson = json_decode($output,true);
$is_no = $outjson['Response']['Available'];

// $ResponseDat = $outjson['Response'];
// echo json_encode($ResponseDat);

// 判断有无错误消息
if(!isset($outjson['Response']['Error'])){
    if($is_no == false){
        echo("已注册");
    }elseif ($is_no == true) {
        echo("未注册");
    }
}else{
    echo($outjson['Response']['Error']['Code']);
}

代码升级

腾讯云云API每秒10次的调用限制很容易碰上。

唯一的解决方法是准备多个账号,但账号分配成了问题。

使用场景:个人使用

均匀分配

统计每个账户调用次数,每次选择最小的使用。

问题:还得弄数据库什么的,太麻烦。

随机(入选)

每次随机选一个账户访问

问题:脸黑的人可能10次都是同一个

超限自动切换

如果超出限制了,自动切换另一个账号再次调用。

问题:这个有点离题了,因为目标是避开限制,节省多次请求消耗的时间,而不是遇到限制如何处理。搭配其他的使用倒是不错。

代码

如果多个账户要按需修改(随机数生成和列表两地方)

$domainname = $_GET['domain'];
$acc_id_list = [["账户一secretId","账户一secretKey "],["账户二secretId","账户二secretKey "]];
$indexP = rand(0,1);
$secretId = $acc_id_list[$indexP][0];
$secretKey = $acc_id_list[$indexP][1];

$host = "domain.tencentcloudapi.com";

API返回值研究(部分)

错误返回值

常见的就两种,一种是签名错误,这个一般在早期出现:

{
    "Response": {
        "Error": {
            "Code": "AuthFailure.SignatureFailure",
            "Message": "The provided credentials could not be validated. Please check your signature is correct."
        },
        "RequestId": "9920bce6-81de-4f2c-bd22-7f95eaad28d8"
    }
}

一种是每秒调用数超出限制,这个比较常见:

{
    "Response": {
        "Error": {
            "Code": "RequestLimitExceeded",
            "Message": "Your current request times equals to `28` in a second, which exceeds the frequency limit `10` for a second. Please reduce the frequency of calls."
        },
        "RequestId": "fd5f460b-3eb7-4a48-a00b-4a39b3fee63b"
    }
}

域名无法注册的返回值

常见的有两种,一种是被注册了没法注册

"该域名已被注册,请选择其他域名"

{
    "Response": {
        "DomainName": "ius.cn",
        "FeeTransfer": 0,
        "RequestId": "2957fcbd-bfb9-48c8-a867-e0a9956d26ec",
        "RealPrice": 29,
        "BlackWord": false,
        "FeeRenew": 0,
        "Available": false,
        "Premium": false,
        "RecordSupport": true,
        "Price": 35,
        "Describe": "",
        "FeeRestore": 0,
        "Period": 1,
        "Reason": "\\u8be5\\u57df\\u540d\\u5df2\\u88ab\\u6ce8\\u518c\\uff0c\\u8bf7\\u9009\\u62e9\\u5176\\u4ed6\\u57df\\u540d"
    }
}

一种是含敏感词无法注册(至少在腾讯云无法注册,别的平台不清楚),但要注意,这只能说明这个域名有敏感词,不能说明没有被注册,腾讯云的逻辑是先检查敏感与否再检查是否被注册了。

"域名包含敏感词不可注册,请选择其他域名"

{
    "Response": {
        "DomainName": "xxx.cn",
        "FeeTransfer": 0,
        "RequestId": "398ad69e-32fb-4286-908a-05f684e755f6",
        "RealPrice": 29,
        "BlackWord": true,
        "FeeRenew": 0,
        "Available": false,
        "Premium": false,
        "RecordSupport": true,
        "Price": 35,
        "Describe": "",
        "FeeRestore": 0,
        "Period": 1,
        "Reason": "\\u57df\\u540d\\u5305\\u542b\\u654f\\u611f\\u8bcd\\u4e0d\\u53ef\\u6ce8\\u518c\\uff0c\\u8bf7\\u9009\\u62e9\\u5176\\u4ed6\\u57df\\u540d"
    }
}

编写笔记

通过curl发送json格式数据的post请求(发送表单数据按代码注释修改)

// 请求外部资源
// 参数:$url,字符串。$post,array。$httpheader,字符数组。
function getHttpResponse_h($url, $post = false,$httpheader, $timeout = 10) {
	// 要先用json_encode()处理,不然就是表单而不是json数据了
	// 传入的数据里要带上Content-Type,标明是application/json
	$po = json_encode($post);
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	// 		$httpheader[] = "Accept: */*";
	// 		$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
	// 		$httpheader[] = "Connection: close";
	curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	if($post) {
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $po);
	}
	$response = curl_exec($ch);
	curl_close($ch);
	return $response;
}

腾讯云API文档签名代码修改

在第一步,文档里的代码是

$canonicalHeaders = "content-type:application/json; charset=utf-8\\n"."host:".$host."\\n";

但是在这次测试里这样写会报错AuthFailure.SignatureFailure

修改成下面这样就不报错了

$canonicalHeaders = "content-type:application/json"."\\n"."host:".$host."\\n";
本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
【有奖征文】用"云API"和PHP写一个查找域名是否可注册的API
在批量查询时,可以直接通过Python调用,比起官网的批量查询要灵活得多(官网的还要先用Python生成列表再复制,而且一次查太多网页还容易出问题)。
<<上一篇
下一篇>>