如何解决PHP cURL下载NSE接口在Linux报Access denied错误
故障根因
NSE站点部署了应用层WAF反爬规则,直接发起无特征的裸cURL请求会被识别为异常爬虫流量,直接返回Access denied。本地XAMPP环境可正常运行,通常是本地出口IP存在浏览器访问留存的合法会话,或本地cURL默认请求特征未命中拦截规则;Linux服务器环境的请求缺少合法会话Cookie、标准浏览器请求头,会直接被防护规则拦截。
本地文件读写权限正常说明故障和本地IO无关,完全是请求侧特征不符合接口校验规则导致。
修复步骤
- 调整请求流程:不能直接请求API接口,需要先访问对应前端页面获取合法的会话Cookie,携带该Cookie再请求API接口
- 补全和真实浏览器一致的请求头,禁止使用cURL默认的请求标识
- 配置cURL标准参数,开启SSL校验、跳转跟随,避免被识别为异常客户端
可直接运行的修复后代码
// 配置路径 $apiUrl = "https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY"; $refererUrl = "https://www.nseindia.com/get-quotes/derivatives?symbol=NIFTY"; $savePath = __DIR__ . DIRECTORY_SEPARATOR . "nifty.json"; $cookiePath = __DIR__ . DIRECTORY_SEPARATOR . "nse_cookie.txt"; // 初始化cURL,第一步先访问前端页面拿合法Cookie $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $refererUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36", CURLOPT_HTTPHEADER => [ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language: en-US,en;q=0.5", "Connection: keep-alive" ], CURLOPT_COOKIEJAR => $cookiePath, CURLOPT_COOKIEFILE => $cookiePath, CURLOPT_TIMEOUT => 10 ]); curl_exec($ch); // 第二步携带Cookie请求API接口,写入文件 $fp = fopen($savePath, "w"); curl_setopt_array($ch, [ CURLOPT_URL => $apiUrl, CURLOPT_FILE => $fp, CURLOPT_HTTPHEADER => [ "Accept: application/json, text/javascript, */*; q=0.01", "Accept-Language: en-US,en;q=0.5", "Referer: " . $refererUrl, "X-Requested-With: XMLHttpRequest" ] ]); curl_exec($ch); // 资源回收 curl_close($ch); fclose($fp); // 如不需要留存Cookie可执行unlink删除临时文件 // unlink($cookiePath);
注意事项
- 接口请求频率不要超过1次/3秒,同IP高频请求会被WAF临时拉黑,同样返回Access denied
- 确保Linux服务器的php-curl扩展已启用,且服务器出口IP未被NSE永久封禁,若部署代码后仍报错可在服务器命令行执行带相同请求头的curl命令测试连通性
- 临时Cookie文件需要给PHP运行用户分配读写权限,否则无法正常存储会话标识
内容的提问来源于stack exchange,提问作者user2398785
相关产品推荐
相关产品推荐

