使用Curl调用Instagram API返回403,Guzzle正常,求解决
解决Curl请求Instagram API返回403 Forbidden的问题
你的Curl请求失败但Guzzle能成功,核心问题是两者对请求的处理逻辑存在差异——Guzzle默认启用了一些你没在Curl中配置的关键选项,同时你还犯了一个请求头格式的错误。下面一步步拆解并修复你的代码:
1. 先修正请求头的格式错误
你当前的$hArray是关联数组,但Curl的CURLOPT_HTTPHEADER要求每个元素是完整的"Key: Value"字符串,而不是键值对结构。Guzzle会自动把关联数组转换成正确的头部格式,但Curl不会——这个错误会导致你的请求头发送异常,直接触发Instagram的403验证。
修改头部数组:
$hArray = [ 'User-Agent: ' . USER_AGENT, 'X-Requested-With: XMLHttpRequest', 'X-Instagram-Gis: cc2796cff28f2a3d71c73a4b61f62d84' ];
2. 添加Guzzle默认启用的关键Curl选项
Guzzle默认开启了几个对Instagram请求至关重要的选项,你的Curl代码里缺失了这些:
- Cookie会话管理:Instagram的API依赖Cookie来验证请求合法性,Guzzle默认使用CookieJar自动处理Cookie,而你的Curl没有配置任何Cookie相关参数。
- 自动跟随重定向:Instagram可能会返回重定向响应,Guzzle默认自动跟随,Curl默认不开启。
- 编码支持:Guzzle默认发送
Accept-Encoding头并自动解码压缩响应,这也会影响请求的合法性验证。
给你的Curl代码补充这些选项:
// 启用Cookie内存存储(自动处理会话Cookie) curl_setopt($ch, CURLOPT_COOKIEJAR, ''); curl_setopt($ch, CURLOPT_COOKIEFILE, ''); // 自动跟随重定向,最多5次 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // 添加Accept-Encoding头(模拟Guzzle默认行为) $hArray[] = 'Accept-Encoding: gzip, deflate, br'; // 启用自动解码压缩响应 curl_setopt($ch, CURLOPT_ENCODING, '');
3. 完整修复后的Curl代码
把以上修改整合后,最终代码如下:
const INSTAGRAM_ENDPOINT = 'https://www.instagram.com/'; const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'; const QUERY_HASH = '42323d64886122307be10013ad2dcc44'; $variables = [ 'id' => '232192182', 'first' => '12', 'after' => 'AQCWAl5VxOspHxLFduBo0kmKu0ILD-jynobaAJQBvRz8S1Vu1rDpz5KnyTADU4hxyOyHAsnrF_8RYXOYIXgwzbdUO41D2rfzL-PZN26HABDtoQ' ]; $endpoint = INSTAGRAM_ENDPOINT . 'graphql/query/?query_hash=' . QUERY_HASH . '&variables=' . json_encode($variables); // 修正后的请求头格式 $hArray = [ 'User-Agent: ' . USER_AGENT, 'X-Requested-With: XMLHttpRequest', 'X-Instagram-Gis: cc2796cff28f2a3d71c73a4b61f62d84', 'Accept-Encoding: gzip, deflate, br' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $endpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $hArray); // 添加Guzzle默认的关键配置 curl_setopt($ch, CURLOPT_COOKIEJAR, ''); curl_setopt($ch, CURLOPT_COOKIEFILE, ''); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); curl_setopt($ch, CURLOPT_ENCODING, ''); // 执行请求并检查错误 $server_output = curl_exec($ch); if(curl_errno($ch)){ echo 'Curl Error: ' . curl_error($ch); } curl_close($ch); echo "<br><br>" . $server_output . "<br><br>";
为什么Postman也失败?
Postman默认不会自动管理Cookie会话,也没有完全模拟Guzzle的请求头和行为。你可以把修复后的Curl代码导入Postman(通过Curl导入功能),就能成功发起请求了。
内容的提问来源于stack exchange,提问作者Hamzeh Soboh
相关产品推荐
相关产品推荐

