更新
This commit is contained in:
@@ -1,293 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ICP备案查询API
|
||||
* 支持通过域名查询网站的ICP备案信息
|
||||
*/
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
|
||||
// 访问计数
|
||||
$counterFile = __DIR__ . '/counter.dat';
|
||||
if (is_writable(dirname($counterFile))) {
|
||||
$counter = (int)@file_get_contents($counterFile);
|
||||
@file_put_contents($counterFile, $counter + 1, LOCK_EX);
|
||||
}
|
||||
|
||||
// 获取请求参数
|
||||
$domain = isset($_GET['domain']) ? trim($_GET['domain']) : '';
|
||||
$type = isset($_GET['type']) ? trim($_GET['type']) : 'json';
|
||||
|
||||
// 验证域名参数
|
||||
if (empty($domain)) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'code' => 400,
|
||||
'message' => '缺少必要参数: domain',
|
||||
'example' => '/api/icp/index.php?domain=example.com'
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 清理域名格式(移除http://或https://)
|
||||
$domain = preg_replace('/^https?:\/\//i', '', $domain);
|
||||
$domain = preg_replace('/\/.*$/', '', $domain);
|
||||
$domain = strtolower(trim($domain));
|
||||
|
||||
// 验证域名格式
|
||||
if (!preg_match('/^([a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i', $domain)) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'code' => 400,
|
||||
'message' => '无效的域名格式',
|
||||
'domain' => $domain
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 查询ICP信息
|
||||
$result = queryICP($domain);
|
||||
|
||||
// 根据type参数返回不同格式
|
||||
if ($type === 'text') {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
if ($result['status'] === 'success') {
|
||||
echo "域名: " . $result['data']['domain'] . "\n";
|
||||
echo "主办单位: " . $result['data']['owner'] . "\n";
|
||||
echo "ICP编号: " . $result['data']['icp'] . "\n";
|
||||
echo "审核时间: " . $result['data']['checkDate'] . "\n";
|
||||
echo "网站名称: " . $result['data']['siteName'] . "\n";
|
||||
} else {
|
||||
echo "查询失败: " . $result['message'];
|
||||
}
|
||||
} else {
|
||||
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询ICP信息
|
||||
* @param string $domain 域名
|
||||
* @return array 返回结果数组
|
||||
*/
|
||||
function queryICP($domain) {
|
||||
$result = [
|
||||
'status' => 'error',
|
||||
'code' => 500,
|
||||
'message' => '查询失败',
|
||||
'domain' => $domain,
|
||||
'data' => null
|
||||
];
|
||||
|
||||
try {
|
||||
// 方法1: 使用微步在线API
|
||||
$apiurl = "https://api.vat.tools/query?domain=" . urlencode($domain);
|
||||
$data = callApi($apiurl);
|
||||
if ($data && is_array($data)) {
|
||||
if (isset($data['icp']) && !empty($data['icp']) && $data['icp'] !== 'N/A') {
|
||||
$result['status'] = 'success';
|
||||
$result['code'] = 200;
|
||||
$result['message'] = '查询成功';
|
||||
$result['data'] = [
|
||||
'domain' => $domain,
|
||||
'icp' => $data['icp'],
|
||||
'owner' => $data['organizer'] ?? $data['owner'] ?? 'N/A',
|
||||
'siteName' => $data['website_name'] ?? $data['name'] ?? 'N/A',
|
||||
'checkDate' => $data['check_date'] ?? $data['approve_date'] ?? 'N/A',
|
||||
'siteNature' => $data['site_nature'] ?? 'N/A',
|
||||
'source' => 'vat.tools'
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// 方法2: 使用爱站网API
|
||||
$apiurl2 = "https://tools.zhuaxia.com/icp?domain=" . urlencode($domain);
|
||||
$data2 = callApi($apiurl2);
|
||||
if ($data2 && is_array($data2) && isset($data2['data'])) {
|
||||
$icpData = $data2['data'];
|
||||
$icp = $icpData['icp'] ?? '';
|
||||
if (!empty($icp) && $icp !== 'N/A') {
|
||||
$result['status'] = 'success';
|
||||
$result['code'] = 200;
|
||||
$result['message'] = '查询成功';
|
||||
$result['data'] = [
|
||||
'domain' => $domain,
|
||||
'icp' => $icp,
|
||||
'owner' => $icpData['unitname'] ?? $icpData['owner'] ?? 'N/A',
|
||||
'siteName' => $icpData['sitename'] ?? $icpData['name'] ?? 'N/A',
|
||||
'checkDate' => $icpData['checkdate'] ?? $icpData['time'] ?? 'N/A',
|
||||
'source' => 'zhuaxia'
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// 方法3: 使用网格API (chaxun)
|
||||
$apiurl3 = "https://www.chaxun.15600.net/service.php?domain=" . urlencode($domain);
|
||||
$data3 = callApi($apiurl3);
|
||||
if ($data3 && is_array($data3)) {
|
||||
$icpNum = $data3['ICP'] ?? $data3['icp'] ?? '';
|
||||
if (!empty($icpNum) && $icpNum !== 'N/A') {
|
||||
$result['status'] = 'success';
|
||||
$result['code'] = 200;
|
||||
$result['message'] = '查询成功';
|
||||
$result['data'] = [
|
||||
'domain' => $domain,
|
||||
'icp' => $icpNum,
|
||||
'owner' => $data3['company'] ?? $data3['owner'] ?? 'N/A',
|
||||
'siteName' => $data3['websitename'] ?? $data3['name'] ?? 'N/A',
|
||||
'checkDate' => $data3['checkTime'] ?? $data3['time'] ?? 'N/A',
|
||||
'source' => 'chaxun'
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// 方法4: 使用AllOrigins代理通过爱站网查询
|
||||
$proxyUrl = "https://api.allorigins.win/get?url=" . urlencode("http://icp.aizhan.com/index.php?domain=" . urlencode($domain));
|
||||
$data4 = callApi($proxyUrl);
|
||||
if ($data4 && isset($data4['contents'])) {
|
||||
$htmlData = $data4['contents'];
|
||||
$parsedData = parseICPFromHTML($htmlData, $domain);
|
||||
if ($parsedData && isset($parsedData['icp']) && $parsedData['icp'] !== 'N/A') {
|
||||
return [
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'message' => '查询成功',
|
||||
'domain' => $domain,
|
||||
'data' => $parsedData
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 方法5: 直接查询爱站网 (HTTP)
|
||||
$apiurl5 = "http://icp.aizhan.com/index.php?domain=" . urlencode($domain);
|
||||
$htmlData = callApi($apiurl5, false);
|
||||
if ($htmlData && strlen($htmlData) > 100) {
|
||||
$parsedData = parseICPFromHTML($htmlData, $domain);
|
||||
if ($parsedData && isset($parsedData['icp']) && $parsedData['icp'] !== 'N/A') {
|
||||
return [
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'message' => '查询成功',
|
||||
'domain' => $domain,
|
||||
'data' => $parsedData
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 都失败返回未备案
|
||||
$result['status'] = 'not_found';
|
||||
$result['code'] = 404;
|
||||
$result['message'] = '未找到ICP备案信息(该域名可能未在中国备案)';
|
||||
|
||||
} catch (Exception $e) {
|
||||
$result['status'] = 'error';
|
||||
$result['code'] = 500;
|
||||
$result['message'] = 'API异常: ' . $e->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用HTTP调用函数
|
||||
*/
|
||||
function callApi($url, $isJson = true) {
|
||||
try {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 8);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode !== 200 || empty($response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($isJson) {
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
return $response;
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从HTML中提取指定字段的值
|
||||
*/
|
||||
function extractFromHTML($html, $label) {
|
||||
$patterns = [
|
||||
'/' . preg_quote($label) . '[^>]*>([^<]+)</',
|
||||
'/<td[^>]*>' . preg_quote($label) . '<\/td>\s*<td[^>]*>([^<]+)<\/td>/',
|
||||
'/<th[^>]*>' . preg_quote($label) . '<\/th>\s*<td[^>]*>([^<]+)<\/td>/',
|
||||
];
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match($pattern, $html, $matches)) {
|
||||
$value = trim(strip_tags($matches[1]));
|
||||
if (!empty($value)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'N/A';
|
||||
}
|
||||
|
||||
/**
|
||||
* 从HTML解析ICP信息
|
||||
*/
|
||||
function parseICPFromHTML($html, $domain) {
|
||||
// 清理HTML
|
||||
$html = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/i', '', $html);
|
||||
$html = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/i', '', $html);
|
||||
|
||||
// 提取ICP编号 - 多种格式
|
||||
$icpPatterns = [
|
||||
'/[\d\u4e00-\u9fa5]+-ICP-\d{8,}/u',
|
||||
'/ICP[\u4e00-\u9fa5]?\d{8,}/u',
|
||||
'/ICP\d{8,}/u',
|
||||
];
|
||||
|
||||
$icp = '';
|
||||
foreach ($icpPatterns as $pattern) {
|
||||
if (preg_match($pattern, $html, $matches)) {
|
||||
$icp = trim($matches[0]);
|
||||
if (!empty($icp)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到ICP号,返回null
|
||||
if (empty($icp) || $icp === 'N/A') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$owner = extractFromHTML($html, '主办单位');
|
||||
$siteName = extractFromHTML($html, '网站名称');
|
||||
$checkDate = extractFromHTML($html, '审核时间');
|
||||
|
||||
return [
|
||||
'domain' => $domain,
|
||||
'icp' => $icp,
|
||||
'owner' => $owner,
|
||||
'siteName' => $siteName,
|
||||
'checkDate' => $checkDate,
|
||||
'source' => 'html-parse'
|
||||
];
|
||||
}
|
||||
?>
|
||||
371
api/tq/index.php
371
api/tq/index.php
@@ -1,126 +1,273 @@
|
||||
|
||||
<?php
|
||||
$file = 'counter.dat';
|
||||
$file = 'counter.dat';
|
||||
|
||||
// 读取并自增
|
||||
$counter = (int)@file_get_contents($file);
|
||||
$counter++;
|
||||
|
||||
// 使用 LOCK_EX 防止并发写入冲突
|
||||
file_put_contents($file, $counter, LOCK_EX);
|
||||
file_put_contents($file, $counter, LOCK_EX);
|
||||
?>
|
||||
<?php
|
||||
// 天气查询 API - 使用国内平台数据
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
|
||||
require '../../need.php';
|
||||
/* End */
|
||||
header("Content-type: application/json");
|
||||
function jiequ($txt1,$q1,$h1)
|
||||
{
|
||||
$txt1=strstr($txt1,$q1);
|
||||
$cd=strlen($q1);
|
||||
$txt1=substr($txt1,$cd);
|
||||
$txt1=strstr($txt1,$h1,"TRUE");
|
||||
return $txt1;
|
||||
// 获取参数
|
||||
$city = $_GET['city'] ?? $_GET['q'] ?? null;
|
||||
$type = $_GET['type'] ?? 'json'; // json, xml
|
||||
$lang = $_GET['lang'] ?? 'zh'; // zh, en
|
||||
|
||||
// 验证参数
|
||||
if (!$city) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'code' => 400,
|
||||
'message' => '缺少必要参数: city (城市名称)',
|
||||
'example' => '/api/tq/?city=北京&type=json&lang=zh'
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
$msg=@$_REQUEST['msg'];
|
||||
$b=@$_REQUEST['b'];
|
||||
$type = @$_REQUEST['type'];
|
||||
$num = @$_REQUEST['num'];
|
||||
new 三日天气多选(Array('name'=>$msg, 'n'=>$b, 'num'=>$num, 'type'=>$type));
|
||||
class 三日天气多选{
|
||||
protected $info = [];
|
||||
protected $Array = [];
|
||||
protected $Msg;
|
||||
public function __construct(Array $Array){
|
||||
foreach($Array as $k=>$v){
|
||||
$this->info[$k] = $v;
|
||||
}
|
||||
$this->ParameterException();
|
||||
}
|
||||
protected function ParameterException(){
|
||||
$name = $this->info['name'];
|
||||
if(empty($name)){
|
||||
$this->Array = Array('code'=>-1, 'text'=>'请输入地名');
|
||||
$this->send();
|
||||
return;
|
||||
}
|
||||
$n = $this->info['n'];
|
||||
if($n > 0 && is_numEric($n)){
|
||||
$this->info['n'] = $n - 1;
|
||||
}else{
|
||||
$this->info['n'] = false;
|
||||
}
|
||||
$num = $this->info['num'];
|
||||
if($num < 1 && is_numEric($num)){
|
||||
$this->info['num'] = 10;
|
||||
}else{
|
||||
$this->info['num'] = 10;
|
||||
}
|
||||
$this->Getdata();
|
||||
return;
|
||||
}
|
||||
protected function Getdata(){
|
||||
$name = ($this->info['name']);
|
||||
$data = need::teacher_curl('http://m.moji.com/api/citysearch/'.$name);
|
||||
$result = preg_match_all("/{\"cityId\":(.*?),\"city_lable\":(.*?),\"counname\":\"(.*?)\",\"id\":(.*?),\"localCounname\":\"(.*?)\",\"localName\":\"(.*?)\",\"localPname\":\"(.*?)\",\"name\":\"(.*?)\",\"pname\":\"(.*?)\"}/",$data,$nute);
|
||||
$n = $this->info['n'];
|
||||
//print_r($nute);exit;
|
||||
$Array = [];
|
||||
$num = $this->info['num'];
|
||||
if($n === false){
|
||||
for ($x=0; $x < $result && $x < $num; $x++) {
|
||||
$jec=$nute[6][$x];
|
||||
$je=$nute[7][$x];
|
||||
$echo .= ($x+1).":".$je."-".$jec."\n";
|
||||
$Array[] = Array('city'=>$je, 'city_t'=>$jec);
|
||||
}
|
||||
$this->Msg = trim($echo);
|
||||
$this->Array = Array('code'=>1, 'text'=>'获取成功', 'data'=>$Array);
|
||||
$this->send();
|
||||
return;
|
||||
}
|
||||
$je=$nute[1][$n];
|
||||
$jec=$nute[6][$n];
|
||||
$data = file_Get_Contents("http://m.moji.com/api/redirect/".$je);
|
||||
$bb=jiequ($data,"<div class=\"weak_wea\">","<div class=\"exponent\">");
|
||||
$bb=str_replace(' ', '', $bb);
|
||||
preg_match_all("/<lidata-high=\"(.*?)\"data-low=\"(.*?)\">/",$bb,$aa);
|
||||
preg_match_all("/<em>(.*?)<\/em>/",$bb,$qq);
|
||||
preg_match_all("/<dd><strong>(.*?)<\/strong><\/dd>/",$bb,$cc);
|
||||
preg_match_all("/<pclass=\"(.*?)\">(.*?)<\/p><dlclass=\"wind\">/",$bb,$dd);
|
||||
preg_match_all("/<dd>(.*?)<\/dd>/",$bb,$ee);
|
||||
preg_match_all("/<dd>(.*?)<\/dd>/",$bb,$ff);
|
||||
if(empty($aa[2][0])){
|
||||
$this->Msg = '不支持';
|
||||
$this->Array = Array('code'=>-2, 'text'=>'不支持');
|
||||
$this->send();
|
||||
return;
|
||||
}
|
||||
$this->Msg = "☁.查询:".$jec."\n☁.日期:".$qq[1][0]."\n☁.温度:".$aa[2][0]."~".$aa[1][0]."℃\n☁.天气:".$cc[1][0]."\n☁.风度:".$ee[1][2]."-".$ff[1][3]."\n☁.空气质量:".$dd[2][0]."\n\n☁.日期:".$qq[1][1]."\n☁.温度:".$aa[2][1]."~".$aa[1][1]."℃\n☁.天气:".$cc[1][1]."\n☁.风度:".$ee[1][6]."-".$ff[1][7]."\n☁.空气质量:".$dd[2][1]."\n\n☁.日期:".$qq[1][2]."\n☁.温度:".$aa[2][2]."~".$aa[1][2]."℃\n☁.天气:".$cc[1][2]."\n☁.风度:".$ee[1][10]."-".$ff[1][11]."\n☁.空气质量:".$dd[2][2]."";
|
||||
|
||||
// 非法字符检查
|
||||
if (!preg_match('/^[\u4e00-\u9fff\w\s\-]+$/u', $city) || strlen($city) > 50) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'code' => 400,
|
||||
'message' => '无效的城市名称'
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = null;
|
||||
$error = null;
|
||||
|
||||
// 方案1: wttr.in 天气服务 (支持中文)
|
||||
// 方案2: 使用中国天气网数据源
|
||||
|
||||
// 尝试方案1: wttr.in 天气服务 (支持中文)
|
||||
$url = "https://wttr.in/" . urlencode($city) . "?format=j1&lang=" . ($lang === 'en' ? 'en' : 'zh-CN');
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) QuickAPI/1.0');
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($http_code == 200 && $response) {
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if ($data && isset($data['current_condition'])) {
|
||||
$current = $data['current_condition'][0];
|
||||
$desc = $current['desc'] ?? [];
|
||||
|
||||
$this->Array = Array('code'=>1, 'text'=>'获取成功', 'data'=>Array('city'=>$jec, 'data'=>Array(Array('Time'=>$qq[1][0], 'temperature'=>$aa[2][0]."~".$aa[1][0]."℃", 'weather'=>$cc[1][0], 'bearing'=>$ee[1][2]."-".$ff[1][3], 'air_quality'=>$dd[2][0]), Array('Time'=>$qq[1][1], 'temperature'=>$aa[2][1]."~".$aa[1][1]."℃", 'weather'=>$cc[1][1], 'bearing'=>$ee[1][6]."-".$ff[1][7], 'air_quality'=>$dd[2][1]), Array('Time'=>$qq[1][2], 'temperature'=>$aa[2][2]."~".$aa[1][2]."℃", 'weather'=>$cc[1][2], 'bearing'=>$ee[1][10]."-".$ff[1][11], 'air_quality'=>$dd[2][2]))));
|
||||
$this->send();
|
||||
return;
|
||||
$result = [
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'city' => $city,
|
||||
'current' => [
|
||||
'temperature' => (float)$current['temp_C'] ?? null,
|
||||
'temperature_f' => (float)$current['temp_F'] ?? null,
|
||||
'feels_like' => (float)$current['FeelsLikeC'] ?? null,
|
||||
'condition' => is_array($desc) ? ($desc[$lang === 'en' ? 'en' : 'zh-CN'] ?? $desc[0] ?? 'Unknown') : 'Unknown',
|
||||
'humidity' => (int)$current['humidity'] ?? null,
|
||||
'wind_speed' => (float)$current['windspeedKmph'] ?? null,
|
||||
'wind_speed_ms' => (float)$current['windspeedKmph'] / 3.6 ?? null,
|
||||
'wind_direction' => $current['winddir16Point'] ?? null,
|
||||
'pressure' => (int)$current['pressure'] ?? null,
|
||||
'precipitation' => (float)$current['precipMM'] ?? null,
|
||||
'visibility' => (float)$current['visibility'] ?? null,
|
||||
'uv_index' => (int)$current['uvIndex'] ?? null,
|
||||
'cloud_cover' => (int)$current['cloudcover'] ?? null
|
||||
],
|
||||
'forecast' => [],
|
||||
'source' => 'wttr.in',
|
||||
'updated_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
// 添加预报数据 (如果可用)
|
||||
if (isset($data['weather']) && is_array($data['weather'])) {
|
||||
foreach ($data['weather'] as $day_idx => $day) {
|
||||
if ($day_idx >= 3) break; // 只显示3天预报
|
||||
|
||||
$forecast_avg = $day['avgtemp_c'] ?? null;
|
||||
$forecast_max = $day['maxtemp_c'] ?? null;
|
||||
$forecast_min = $day['mintemp_c'] ?? null;
|
||||
$forecast_desc = $day['hourly'][0]['desc'] ?? [];
|
||||
|
||||
$result['forecast'][] = [
|
||||
'date' => $day['date'] ?? null,
|
||||
'avg_temp' => (float)$forecast_avg,
|
||||
'max_temp' => (float)$forecast_max,
|
||||
'min_temp' => (float)$forecast_min,
|
||||
'condition' => is_array($forecast_desc) ? ($forecast_desc[$lang === 'en' ? 'en' : 'zh-CN'] ?? $forecast_desc[0] ?? 'Unknown') : 'Unknown',
|
||||
'avg_humidity' => (int)$day['avghumidity'] ?? null,
|
||||
'total_snow' => (float)$day['totalSnow_cm'] ?? null,
|
||||
'uv_index' => (int)$day['uvIndex'] ?? null
|
||||
];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$error = '无法解析天气数据';
|
||||
}
|
||||
public function send(){
|
||||
$type = $this->info['type'];
|
||||
$data = $this->Array;
|
||||
if($data['data']['city']){
|
||||
Switch($type){
|
||||
case 'text':
|
||||
need::send($this->Msg, 'text');
|
||||
break;
|
||||
default:
|
||||
need::send($data);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
Switch($type){
|
||||
case 'text':
|
||||
need::send($this->Msg, 'text');
|
||||
break;
|
||||
default:
|
||||
need::send($data);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$error = '无法连接到天气服务或城市不存在';
|
||||
}
|
||||
|
||||
// 如果主方案失败,尝试方案2: 心知天气 API (中国天气网数据)
|
||||
if (!$result) {
|
||||
// 心知天气免费API - 无需key即可使用基础功能
|
||||
$url2 = "https://api.seniverse.com/v1/now.json?location=" . urlencode($city) . "&language=" . ($lang === 'en' ? 'en' : 'zh-Hans');
|
||||
|
||||
$ch2 = curl_init();
|
||||
curl_setopt($ch2, CURLOPT_URL, $url2);
|
||||
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch2, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch2, CURLOPT_USERAGENT, 'Mozilla/5.0 QuickAPI/1.0');
|
||||
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
$response2 = curl_exec($ch2);
|
||||
$http_code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch2);
|
||||
|
||||
if ($http_code2 == 200 && $response2) {
|
||||
$data2 = json_decode($response2, true);
|
||||
|
||||
if ($data2 && isset($data2['results']) && count($data2['results']) > 0) {
|
||||
$results = $data2['results'][0];
|
||||
$location = $results['location'];
|
||||
$now = $results['now'];
|
||||
|
||||
$result = [
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'city' => $location['name'] ?? $city,
|
||||
'region' => $location['country'] ?? null,
|
||||
'coordinates' => [
|
||||
'latitude' => (float)$location['lat'] ?? null,
|
||||
'longitude' => (float)$location['lon'] ?? null
|
||||
],
|
||||
'current' => [
|
||||
'temperature' => (float)$now['temperature'] ?? null,
|
||||
'feels_like' => (float)$now['feels_like'] ?? null,
|
||||
'condition' => $now['text'] ?? 'Unknown',
|
||||
'condition_code' => $now['code'] ?? null,
|
||||
'wind_speed' => (float)$now['wind_speed'] ?? null,
|
||||
'wind_speed_kph' => ((float)$now['wind_speed'] * 3.6) ?? null,
|
||||
'wind_direction' => $now['wind_direction'] ?? null,
|
||||
'wind_direction_code' => $now['wind_direction_code'] ?? null,
|
||||
'humidity' => (int)$now['humidity'] ?? null,
|
||||
'visibility' => (float)$now['visibility'] ?? null,
|
||||
'pressure' => (int)$now['pressure'] ?? null
|
||||
],
|
||||
'source' => '心知天气(中国天气数据)',
|
||||
'updated_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果仍未获得数据,尝试方案3: 和风天气 API
|
||||
if (!$result) {
|
||||
// 和风天气免费API
|
||||
$url3 = "https://devapi.qweather.com/v7/weather/now?location=" . urlencode($city) . "&lang=" . ($lang === 'en' ? 'en' : 'zh');
|
||||
|
||||
$ch3 = curl_init();
|
||||
curl_setopt($ch3, CURLOPT_URL, $url3);
|
||||
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch3, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch3, CURLOPT_USERAGENT, 'Mozilla/5.0 QuickAPI/1.0');
|
||||
curl_setopt($ch3, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
$response3 = curl_exec($ch3);
|
||||
$http_code3 = curl_getinfo($ch3, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch3);
|
||||
|
||||
if ($http_code3 == 200 && $response3) {
|
||||
$data3 = json_decode($response3, true);
|
||||
|
||||
if ($data3 && isset($data3['now'])) {
|
||||
$now = $data3['now'];
|
||||
|
||||
$result = [
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'city' => $data3['fxLink'] ? substr($data3['fxLink'], strrpos($data3['fxLink'], '/') + 1) : $city,
|
||||
'current' => [
|
||||
'temperature' => (int)$now['temp'] ?? null,
|
||||
'feels_like' => (int)$now['feelsLike'] ?? null,
|
||||
'condition_code' => $now['icon'] ?? null,
|
||||
'condition' => $now['text'] ?? 'Unknown',
|
||||
'wind_speed' => (float)$now['windSpeed'] ?? null,
|
||||
'wind_direction' => $now['windDir'] ?? null,
|
||||
'wind_direction_code' => (int)$now['wind_degree'] ?? null,
|
||||
'humidity' => (int)$now['humidity'] ?? null,
|
||||
'pressure' => (int)$now['pressure'] ?? null,
|
||||
'visibility' => (int)$now['vis'] ?? null,
|
||||
'dew_point' => (int)$now['dewPoint'] ?? null
|
||||
],
|
||||
'source' => '和风天气(中国天气数据)',
|
||||
'updated_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
if ($result) {
|
||||
if ($type === 'xml' || $type === 'XML') {
|
||||
header('Content-type: application/xml; charset=UTF-8');
|
||||
echo arrayToXml($result, null, null, 'weather');
|
||||
} else {
|
||||
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
}
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'code' => 500,
|
||||
'message' => $error ?? '天气服务暂时不可用',
|
||||
'tips' => '请尝试使用其他城市名称或稍后再试'
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
// 数组转XML函数
|
||||
function arrayToXml($arr, $dom = null, $node = null, $root = 'root', $cdata = false) {
|
||||
if (!$dom) {
|
||||
$dom = new DOMDocument('1.0', 'utf-8');
|
||||
}
|
||||
if (!$node) {
|
||||
$node = $dom->createElement($root);
|
||||
$dom->appendChild($node);
|
||||
}
|
||||
|
||||
foreach ($arr as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$key = 'item';
|
||||
}
|
||||
$child_node = $dom->createElement($key);
|
||||
$node->appendChild($child_node);
|
||||
|
||||
if (!is_array($value)) {
|
||||
if (!$cdata) {
|
||||
$data = $dom->createTextNode((string)$value);
|
||||
} else {
|
||||
$data = $dom->createCDATASection((string)$value);
|
||||
}
|
||||
$child_node->appendChild($data);
|
||||
} else {
|
||||
arrayToXml($value, $dom, $child_node, $root, $cdata);
|
||||
}
|
||||
}
|
||||
|
||||
return $dom->saveXML();
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -299,54 +299,28 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ICP备案查询",
|
||||
"description": "查询网站的ICP备案信息,支持多个数据源查询,返回ICP备案号、主办单位、网站名称、审核时间等详细信息",
|
||||
"path": "/api/icp/index.php",
|
||||
"method": "GET",
|
||||
"params": [
|
||||
{
|
||||
"name": "domain",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "要查询的域名(支持带http://或https://前缀,会自动清理)"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "返回格式[json|text],默认为json。json返回JSON格式备案数据,text返回格式化纯文本"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "天气查询",
|
||||
"description": "查询指定城市的天气信息,支持返回3天天气预报,包含温度、天气状况、风力等信息",
|
||||
"name": "实时天气查询",
|
||||
"description": "查询实时天气信息,支持国内天气数据源(wttr.in、心知天气、和风天气),返回温度、风速、湿度、气压、紫外线指数等详细气象数据,支持中英文双语",
|
||||
"path": "/api/tq/index.php",
|
||||
"method": "GET",
|
||||
"params": [
|
||||
{
|
||||
"name": "msg",
|
||||
"name": "city",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "城市名称或地名"
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"description": "选择第几个城市结果(当搜索结果多于1个时),不提供则返回所有搜索结果列表"
|
||||
},
|
||||
{
|
||||
"name": "num",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"description": "返回结果数量,默认为10"
|
||||
"description": "城市名称,如:北京、上海、深圳、杭州等中文城市名称"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "返回格式[json|text],默认为json"
|
||||
"description": "返回格式[json|xml],默认为json。json返回JSON格式数据,xml返回XML格式"
|
||||
},
|
||||
{
|
||||
"name": "lang",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "语言[zh|en],默认为zh(中文)。zh返回中文天气描述,en返回英文"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user