PHP使用Curl无法读取华盛顿邮报RSS Feed问题求助
解决华盛顿邮报RSS Feed的PHP curl HTTP/2连接错误问题
问题回顾
原本正常运行的PHP curl脚本,在2024年8月2日开始返回错误:
HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)
尝试设置CURLOPT_REFERER、CURLOPT_USERAGENT无效;切换到HTTP/1.1后出现超时,浏览器直接访问RSS地址正常,file_get_contents也无法工作。
解决建议
1. 优化curl请求参数,模拟完整浏览器行为
华盛顿邮报可能更新了反爬策略,需要更贴近真实浏览器的请求头和安全配置。以下是调整后的示例代码:
<?php $curl = curl_init(); // 模拟浏览器请求头 $headers = [ 'Accept: application/rss+xml, application/xml, text/xml', 'Accept-Encoding: gzip, deflate, br', 'Accept-Language: en-US,en;q=0.9', 'Connection: keep-alive' ]; curl_setopt_array($curl, [ CURLOPT_URL => 'https://www.washingtonpost.com/arcio/rss/', // 使用主流浏览器UA CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', CURLOPT_HTTPHEADER => $headers, // 强制使用TLS 1.3,符合现代网站安全要求 CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_3, CURLOPT_RETURNTRANSFER => true, // 自动处理压缩编码 CURLOPT_ENCODING => '', // 启用详细日志,便于排查连接问题 CURLOPT_VERBOSE => true, CURLOPT_STDERR => fopen('php://stderr', 'w'), // 处理可能的重定向 CURLOPT_FOLLOWLOCATION => true, CURLOPT_TIMEOUT => 30 ]); $result = curl_exec($curl); if ($result === false) { echo "Error: " . curl_error($curl) . "\n"; echo "Error code: " . curl_errno($curl) . "\n"; } else { // 手动解压gzip内容(部分场景下curl自动处理失效) $info = curl_getinfo($curl); if (isset($info['content_encoding']) && $info['content_encoding'] === 'gzip') { $result = gzdecode($result); } echo $result . "\n"; } curl_close($curl); ?>
2. 检查并更新curl版本
旧版本的curl对HTTP/2的支持存在bug,执行以下命令查看当前curl版本:
curl --version
确保版本支持HTTP/2(输出中包含HTTP2)和TLS 1.3,若版本过旧,更新curl及libcurl到最新稳定版。
3. 调整file_get_contents的上下文配置
如果需要使用file_get_contents,可添加完整的请求上下文:
<?php $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => implode("\r\n", [ 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', 'Accept: application/rss+xml, application/xml, text/xml', 'Accept-Encoding: gzip, deflate, br', 'Accept-Language: en-US,en;q=0.9' ]), 'timeout' => 30 ], 'ssl' => [ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT ] ]); $result = file_get_contents('https://www.washingtonpost.com/arcio/rss/', false, $context); if ($result === false) { print_r(error_get_last()); } else { // 检查并解压gzip内容 if (substr($result, 0, 2) === "\x1f\x8b") { $result = gzdecode($result); } echo $result; } ?>
4. 验证RSS地址及Cookie需求
- 确认浏览器访问的RSS地址与脚本中一致,部分网站可能会动态重定向RSS地址
- 查看浏览器请求的Cookie信息,若网站需要特定Cookie才能访问RSS,可在curl中添加
CURLOPT_COOKIE参数传入对应的Cookie值
内容的提问来源于stack exchange,提问作者Percy
相关产品推荐
相关产品推荐

