You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:非管理员如何用PHP获取Shoutcast V2的/stats?sid=1数据

解决Shoutcast V2 /stats?sid=1 数据获取问题

Hey Andrew, 我完全懂你搜了好几个小时的崩溃感——作为普通爱好者碰不到管理员权限的XML接口,只能从公开的stats页面抠数据确实有点挠头。我之前帮朋友处理过类似需求,给你分享几个亲测有效的方案:

核心问题说明

首先得明确:Shoutcast V2的/stats?sid=1返回的是HTML页面(不是标准XML),所以直接用SimpleXML肯定会报错。咱们的思路是先拿到页面内容,再从HTML里提取需要的字段。

方案一:用cURL获取内容+DOM解析(最可靠)

很多时候file_get_contents失败,是因为Shoutcast服务器会拦截默认的PHP请求头。用cURL可以模拟浏览器请求,避开拦截,再用DOM解析HTML结构,比正则靠谱多了:

步骤1:用cURL请求页面

$shoutcastUrl = 'http://你的服务器地址:端口/stats?sid=1';

// 初始化cURL
$ch = curl_init($shoutcastUrl);
// 把返回内容存到变量里,不直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 模拟浏览器的User-Agent,避免被服务器拦截
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36');
// 如果服务器是HTTPS,测试阶段可以临时关闭SSL验证(正式环境建议开启)
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// 执行请求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// 检查请求是否成功
if ($httpCode !== 200) {
    die("请求失败,HTTP状态码:$httpCode");
}

步骤2:解析HTML提取数据

打开你要爬的/stats?sid=1页面,右键查看源码,找到标题、听众数、流派所在的标签结构(大部分Shoutcast V2的stats页面是表格布局)。然后用DOMXPath定位元素:

// 处理HTML编码问题,避免乱码
$dom = new DOMDocument();
// 忽略HTML的语法错误(Shoutcast的页面可能不标准)
libxml_use_internal_errors(true);
$dom->loadHTML(mb_convert_encoding($response, 'HTML-ENTITIES', 'UTF-8'));
libxml_clear_errors();

$xpath = new DOMXPath($dom);

// 提取当前播放标题(根据你看到的页面结构调整XPath)
$titleNodes = $xpath->query('//span[@class="streamtitle"]');
$currentTitle = $titleNodes->length > 0 ? trim($titleNodes->item(0)->nodeValue) : '无法获取标题';

// 提取当前听众数
$listenersNodes = $xpath->query('//td[contains(text(), "Current Listeners")]/following-sibling::td');
$currentListeners = $listenersNodes->length > 0 ? trim($listenersNodes->item(0)->nodeValue) : '无法获取听众数';

// 提取流派
$genreNodes = $xpath->query('//td[contains(text(), "Genre")]/following-sibling::td');
$currentGenre = $genreNodes->length > 0 ? trim($genreNodes->item(0)->nodeValue) : '无法获取流派';

// 输出结果
echo "当前播放:{$currentTitle}\n";
echo "在线听众:{$currentListeners}\n";
echo "流派:{$currentGenre}\n";

方案二:正则表达式(应急用)

如果DOM解析太麻烦,或者页面结构特别简单,可以用正则快速提取,但要注意:页面结构一变,正则就失效了,所以只适合临时用:

// 提取听众数
preg_match('/Current Listeners:\s*(\d+)/i', $response, $listenerMatches);
$listeners = isset($listenerMatches[1]) ? $listenerMatches[1] : '0';

// 提取流派
preg_match('/Genre:\s*(.+)/i', $response, $genreMatches);
$genre = isset($genreMatches[1]) ? trim($genreMatches[1]) : '未知';

// 提取标题
preg_match('/Stream Title:\s*(.+)/i', $response, $titleMatches);
$title = isset($titleMatches[1]) ? trim($titleMatches[1]) : '无标题';

额外注意事项

  • 如果cURL还是请求失败,可以试试添加CURLOPT_REFERER,设置为服务器的主页地址,有些服务器会检查Referer。
  • 不要频繁请求,避免被服务器封禁IP。
  • 不同Shoutcast服务器的stats页面结构可能略有差异,一定要自己看源码调整XPath或正则表达式!

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:11:07