求助:非管理员如何用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
相关产品推荐
相关产品推荐

