PHP cURL获取BBC RSS返回URL列表而非XML,与控制台cURL结果不符
解决思路与修复方案
问题核心分析
你遇到的问题主要来自两个方面:
- 响应拆分逻辑错误:启用
CURLOPT_FOLLOWLOCATION后,若存在重定向,响应会包含多组HTTP头信息,直接用\r\n\r\n拆分会导致正文混入后续重定向的头内容,最终提取的"XML"实际是混乱的片段。 - 请求头配置偏差:PHP cURL与控制台cURL的请求行为存在细微差异,导致服务器返回非预期的内容格式。
分步修复方案
1. 重构cURL请求函数,分离头信息与正文
不要通过CURLOPT_HEADER => true混合头信息和正文,改用CURLOPT_HEADERFUNCTION单独捕获头信息,确保正文纯净:
function curl_get($url) { $headers = []; $client = curl_init(); curl_setopt_array($client, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_HTTPHEADER => [ 'Accept: application/rss+xml, application/xml;q=0.9, */*;q=0.8', 'Accept-Encoding: gzip, deflate, br' ], CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', CURLOPT_ENCODING => '', // 自动处理压缩格式 CURLOPT_HEADERFUNCTION => function($curl, $header) use (&$headers) { $len = strlen($header); $header = trim($header); if (!empty($header)) { $headers[] = $header; } return $len; } ]); $response = curl_exec($client); // 检查cURL请求错误 if (curl_errno($client)) { $error = curl_error($client); curl_close($client); throw new Exception("cURL Error: {$error}"); } // 获取关键响应信息 $statusCode = curl_getinfo($client, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($client, CURLINFO_CONTENT_TYPE); curl_close($client); return [ 'status_code' => $statusCode, 'content_type' => $contentType, 'headers' => $headers, 'body' => $response ]; }
2. 正确提取并验证XML内容
调用重构后的函数后,直接使用返回的body字段即可,无需手动拆分:
$result = curl_get('https://feeds.bbci.co.uk/news/politics/rss.xml'); // 输出调试信息 echo "状态码: {$result['status_code']}\n"; echo "内容类型: {$result['content_type']}\n"; echo "响应头:\n" . implode("\n", $result['headers']) . "\n"; echo "\nXML内容:\n{$result['body']}";
3. 关键调整说明
- 优化Accept头:改用
application/rss+xml作为优先接受类型,更符合RSS Feed的标准,避免服务器返回文本格式的降级内容。 - 移除冗余配置:删除
CURLOPT_CUSTOMREQUEST => 'GET',GET是cURL默认请求方法,手动设置可能引入意外行为。 - 增加错误捕获:新增cURL错误检查,快速定位连接或请求层面的问题。
- 自动处理压缩:保留
CURLOPT_ENCODING => '',让cURL自动处理gzip/deflate压缩,避免乱码或内容截断。
4. 额外调试建议
- 对比请求头:在控制台执行
curl -v https://feeds.bbci.co.uk/news/politics/rss.xml,复制控制台的请求头到PHP的CURLOPT_HTTPHEADER中,确保请求行为完全一致。 - 检查cURL版本:旧版本cURL可能对HTTPS或重定向处理存在兼容问题,尝试升级PHP的cURL扩展。
内容的提问来源于stack exchange,提问作者toorboon
相关产品推荐
相关产品推荐

