引言
看到标题想必你已经懂了,至于具体的实现过程我只能说三个字"F12"
实现代码-PHP
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
class Webquery
{
private $typj = [
0 => '{"pageNum": "", "pageSize": "", "unitName": "", "serviceType": 1}'
];
private $cookieHeaders = [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32'
];
private $home = 'https://beian.miit.gov.cn/';
private $url = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/auth';
private $getCheckImage = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/image/getCheckImagePoint';
private $checkImage = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/image/checkImage';
private $queryByCondition = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/icpAbbreviateInfo/queryByCondition';
private $p_uuid = '';
private $session;
private $baseHeader = [];
private $baseHeader2 = [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32',
'Origin' => 'https://beian.miit.gov.cn',
'Referer' => 'https://beian.miit.gov.cn/',
'Cookie' => '__jsluid_s=',
'Accept' => 'application/json, text/plain, */*',
'Content-Type' => 'application/json'
];
private $token = '';
private $secretKey = '';
public function __construct()
{
$this->session = curl_init();
curl_setopt($this->session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->session, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this->session, CURLOPT_SSL_VERIFYHOST, false);
}
public function __destruct()
{
curl_close($this->session);
}
private function getCookie()
{
curl_setopt($this->session, CURLOPT_URL, $this->home);
curl_setopt($this->session, CURLOPT_HTTPHEADER, $this->formatHeaders($this->cookieHeaders));
curl_setopt($this->session, CURLOPT_HEADER, true);
curl_setopt($this->session, CURLOPT_NOBODY, true);
$response = curl_exec($this->session);
preg_match('/__jsluid_s=([0-9a-z]{32})/', $response, $matches);
curl_setopt($this->session, CURLOPT_HEADER, false);
curl_setopt($this->session, CURLOPT_NOBODY, false);
return $matches[1] ?? '';
}
private function getToken()
{
$timeStamp = round(microtime(true) * 1000);
$authSecret = 'testtest' . $timeStamp;
$authKey = md5($authSecret);
$cookie = $this->getCookie();
$this->baseHeader = [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32',
'Origin' => 'https://beian.miit.gov.cn',
'Referer' => 'https://beian.miit.gov.cn/',
'Cookie' => '__jsluid_s=' . $cookie,
'Accept' => 'application/json, text/plain, */*'
];
$this->baseHeader2['Cookie'] = '__jsluid_s=' . $cookie;
curl_setopt($this->session, CURLOPT_URL, $this->url);
curl_setopt($this->session, CURLOPT_POST, true);
curl_setopt($this->session, CURLOPT_POSTFIELDS, ['authKey' => $authKey, 'timeStamp' => $timeStamp]);
curl_setopt($this->session, CURLOPT_HTTPHEADER, $this->formatHeaders($this->baseHeader));
$response = curl_exec($this->session);
$data = json_decode($response, true);
return $data['params']['bussiness'] ?? '';
}
private function getPointJson($value, $key)
{
$jsonStr = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$jsonStr = str_replace([' ', "\t", "\n", "\r"], '', $jsonStr);
$blockSize = 16;
$dataLen = strlen($jsonStr);
$pad = $blockSize - ($dataLen % $blockSize);
$paddedData = $jsonStr . str_repeat(chr($pad), $pad);
$encrypted = openssl_encrypt(
$paddedData,
'AES-128-ECB',
$key,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING
);
return base64_encode($encrypted);
}
private function getClientUid()
{
$characters = '0123456789abcdef';
$uniqueId = array_fill(0, 36, '0');
for ($i = 0; $i < 36; $i++) {
$uniqueId[$i] = $characters[rand(0, strlen($characters) - 1)];
}
$uniqueId[14] = '4';
$uniqueId[19] = $characters[(3 & hexdec($uniqueId[19])) | 8];
$uniqueId[8] = $uniqueId[13] = $uniqueId[18] = $uniqueId[23] = '-';
return json_encode(['clientUid' => 'point-' . implode('', $uniqueId)]);
}
public function checkImg()
{
$this->token = $this->getToken();
try {
$data = $this->getClientUid();
$clientUid = json_decode($data, true)['clientUid'];
$headers = $this->baseHeader;
$headers['Content-Length'] = strlen($data);
$headers['Token'] = $this->token;
$headers['Content-Type'] = 'application/json';
curl_setopt($this->session, CURLOPT_URL, $this->getCheckImage);
curl_setopt($this->session, CURLOPT_POST, true);
curl_setopt($this->session, CURLOPT_POSTFIELDS, $data);
curl_setopt($this->session, CURLOPT_HTTPHEADER, $this->formatHeaders($headers));
$response = curl_exec($this->session);
$res = json_decode($response, true);
$this->p_uuid = $res['params']['uuid'] ?? '';
$this->secretKey = $res['params']['secretKey'] ?? '';
return [
"big_image" => $res['params']['bigImage'] ?? '',
"small_image" => $res['params']['smallImage'] ?? '',
"p_uuid" => $this->p_uuid,
"token" => $this->token,
"secretKey" => $this->secretKey,
"clientUid" => $clientUid,
'cookie' => $this->baseHeader2['Cookie'] ?? '',
'success' => true
];
} catch (\Exception $e) {
return false;
}
}
private function formatHeaders($headers)
{
$formatted = [];
foreach ($headers as $key => $value) {
$formatted[] = "$key: $value";
}
return $formatted;
}
public function icp_search($name, $pageNum = '', $pageSize = '')
{
if(empty($name)) return ["code" => 122, "msg" => "查询失败: 请输入正确的域名"];
return $this->autoget($name, 0, $pageNum, $pageSize);
}
private function autoget($name, $sp, $pageNum = '', $pageSize = '', $b = 1)
{
try {
if ($b == 1) {
$data = $this->getBeian($name, $sp, $pageNum, $pageSize);
}
return $data;
} catch (\Exception $e) {
return ["code" => 122, "msg" => "查询失败: " . $e->getMessage()];
}
}
private function getBeian($name, $sp, $pageNum, $pageSize)
{
$info = json_decode($this->typj[$sp], true);
$info['pageNum'] = $pageNum;
$info['pageSize'] = $pageSize;
$info['unitName'] = $name;
return $this->checkImg();
}
private function phpjsonstring_tophparray($str)
{
$array = [];
$phpCode = '$array = ' . $str . ';';
eval($phpCode);
$newarr = $array;
return $newarr;
}
public function icp_auth($x_y_list, $p_uuid, $token, $secretKey, $clientUid, $domain, $cookie_c)
{
$client = new Client([
'verify' => false,
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32',
'Origin' => 'https://beian.miit.gov.cn',
'Referer' => 'https://beian.miit.gov.cn/',
'Cookie' => $cookie_c,
'Accept' => 'application/json, text/plain, */*',
'Content-Type' => 'application/json',
'Uuid' => $p_uuid,
'Token' => $token
]
]);
try {
$info = json_decode($this->typj[0], true);
$info['pageNum'] = '';
$info['pageSize'] = '';
$info['unitName'] = $domain;
$pointJson = $this->getPointJson($this->phpjsonstring_tophparray($x_y_list), $secretKey);
$verifyData = [
"token" => $p_uuid,
"secretKey" => $secretKey,
"clientUid" => $clientUid,
"pointJson" => $pointJson
];
$verifyResponse = $client->post($this->checkImage, [
'json' => $verifyData,
'headers' => [
'Content-Length' => strlen(json_encode($verifyData))
]
]);
$resData = json_decode($verifyResponse->getBody(), true);
if (!$resData['success']) {
return ['code' => 201, 'error' => '验证码验证失败'];
}
$sign = $resData["params"]["sign"] ?? '';
if ($sign === 'verf error') {
return ['code' => 201, 'error' => '验证码识别失败'];
}
$infoJson = json_encode($info, JSON_UNESCAPED_UNICODE);
$queryResponse = $client->post($this->queryByCondition, [
'body' => $infoJson,
'headers' => [
'Content-Length' => strlen($infoJson),
'Sign' => $sign
]
]);
return json_decode($queryResponse->getBody(), true);
} catch (GuzzleException $e) {
return ["code" => 122, "msg" => "查询失败: " . $e->getMessage()];
}
}
}
简单文档
类概述
Webquery 类用于通过工信部ICP备案查询接口进行相关信息查询,包含验证码处理、token获取、备案信息查询等功能
主要功能:获取验证码图片、验证验证码、查询ICP备案信息等
私有属性
$typj
查询参数模板数组,包含不同服务类型的查询参数结构。
private $typj = [
0 => '{"pageNum": "", "pageSize": "", "unitName": "", "serviceType": 1}',
1 => '{"pageNum": "", "pageSize": "", "unitName": "", "serviceType": 6}',
2 => '{"pageNum": "", "pageSize": "", "unitName": "", "serviceType": 7}',
3 => '{"pageNum": "", "pageSize": "", "unitName": "", "serviceType": 8}'
];
$cookieHeaders
获取Cookie时使用的HTTP头信息。
private $cookieHeaders = [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32'
];
$home
工信部ICP备案查询首页URL。
private $home = 'https://beian.miit.gov.cn/';
$url
认证接口URL。
private $url = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/auth';
$getCheckImage
获取验证码图片接口URL。
private $getCheckImage = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/image/getCheckImagePoint';
$checkImage
验证验证码接口URL。
private $checkImage = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/image/checkImage';
$queryByCondition
按条件查询备案信息接口URL。
private $queryByCondition = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/icpAbbreviateInfo/queryByCondition';
$p_uuid
验证码相关的UUID。
private $p_uuid = '';
$session
cURL会话句柄。
private $session;
baseHeader、baseHeader、baseHeader2
基础HTTP头信息,用于接口请求。
$token
接口请求所需的token。
private $token = '';
$secretKey
验证码相关的密钥。
private $secretKey = '';
构造函数与析构函数
__construct()
初始化cURL会话,设置cURL选项(返回结果、禁用SSL验证)。
public function __construct()
__destruct()
关闭cURL会话。
public function __destruct()
私有方法
getCookie()
从首页获取Cookie(__jsluid_s)。
private function getCookie()
**返回值:**字符串,获取到的Cookie值,失败则返回空字符串。
getToken()
获取接口请求所需的token。通过生成时间戳、authKey,调用认证接口获取。
private function getToken()
**返回值:**字符串,获取到的token,失败则返回空字符串。
getPointJson($value, $key)
对坐标信息进行AES-128-ECB加密,并返回Base64编码结果。
private function getPointJson($value, $key)
参数 | 类型 | 描述 |
---|---|---|
$value | mixed | 需要加密的坐标信息 |
$key | string | 加密密钥 |
**返回值:**字符串,加密后的Base64编码结果。
getClientUid()
生成客户端唯一标识(clientUid),格式为UUID。
private function getClientUid()
**返回值:**字符串,包含clientUid的JSON字符串。
formatHeaders($headers)
将关联数组格式的HTTP头转换为cURL所需的格式(“Key: Value”)。
private function formatHeaders($headers)
参数 | 类型 | 描述 |
---|---|---|
$headers | array | 关联数组形式的HTTP头 |
**返回值:**数组,格式化后的HTTP头数组。
autoget($name, $sp, $pageNum = ‘’, $pageSize = ‘’, $b = 1)
自动获取备案信息的封装方法,调用getBeian方法。
private function autoget($name, $sp, $pageNum = '', $pageSize = '', $b = 1)
参数 | 类型 | 描述 |
---|---|---|
$name | string | 查询的单位名称或域名 |
$sp | int | 服务类型索引(对应$typj数组) |
$pageNum | string | 页码,可选 |
$pageSize | string | 每页条数,可选 |
$b | int | 标志位,默认为1 |
**返回值:**数组,查询结果或错误信息。
getBeian($name, $sp, $pageNum, $pageSize)
准备备案查询参数,调用checkImg()获取验证码相关信息。
private function getBeian($name, $sp, $pageNum, $pageSize)
参数 | 类型 | 描述 |
---|---|---|
$name | string | 查询的单位名称或域名 |
$sp | int | 服务类型索引 |
$pageNum | string | 页码 |
$pageSize | string | 每页条数 |
**返回值:**数组,验证码相关信息(同checkImg()返回值)。
phpjsonstring_tophparray($str)
将JSON格式的字符串转换为PHP数组(使用eval实现)。
private function phpjsonstring_tophparray($str)
参数 | 类型 | 描述 |
---|---|---|
$str | string | JSON格式的字符串 |
**返回值:**数组,转换后的PHP数组。
公共方法
checkImg()
获取验证码图片信息,包括大图、小图、UUID、token、密钥等。
public function checkImg()
**返回值:**数组,包含验证码相关信息(big_image、small_image、p_uuid、token等),失败返回false。
icp_search($name, $pageNum = ‘’, $pageSize = ‘’)
查询ICP备案信息的入口方法,调用autoget方法。
public function icp_search($name, $pageNum = '', $pageSize = '')
参数 | 类型 | 描述 |
---|---|---|
$name | string | 查询的域名或单位名称 |
$pageNum | string | 页码,可选 |
$pageSize | string | 每页条数,可选 |
**返回值:**数组,查询结果或错误信息(如未输入域名则返回错误提示)。
icp_auth($x_y_list, $p_uuid, $token, $secretKey, $clientUid, $domain, $cookie_c)
验证验证码并查询ICP备案信息。使用Guzzle客户端发送请求,先验证验证码,再查询备案信息。
public function icp_auth($x_y_list, $p_uuid, $token, $secretKey, $clientUid, $domain, $cookie_c)
参数 | 类型 | 描述 |
---|---|---|
$x_y_list | string | 验证码坐标信息的JSON字符串 |
$p_uuid | string | 验证码UUID |
$token | string | 接口token |
$secretKey | string | 验证码密钥 |
$clientUid | string | 客户端唯一标识 |
$domain | string | 要查询的域名 |
$cookie_c | string | Cookie信息 |
**返回值:**数组,备案查询结果、验证码验证失败信息或异常信息。
使用流程概述
- 实例化Webquery类:
$webquery = new Webquery();
- 调用checkImg()获取验证码信息:
$verifyInfo = $webquery->icp_search(域名);
- 用户处理验证码,获取坐标信息
- 调用icp_auth()验证验证码并查询备案信息:
$result = $webquery->icp_auth(...);
收尾
如果想要纯自动化处理,可以使用OCR或者自行训练一个模型出来(数据集类型为图片)
自己拿去悄悄用吧,无套路,我是良心博主❤