PHP使用cURL请求TMview API无法获取JSON响应问题求助
问题排查与修复方案
问题根因
你请求的站点使用了Akamai反爬校验机制,首次请求只会返回校验Cookie,不会返回业务数据,你的代码存在以下几个问题导致无法拿到预期JSON:
- 超时设置过短:
CURLOPT_TIMEOUT设为1秒,网络延迟高时请求直接被截断 - 错误传递本地Cookie:你把当前请求的
PHPSESSID传给了目标站点,目标站点不认这个Cookie,反而需要你主动携带它首次返回的TS开头的校验Cookie发起二次请求 - 请求头配置错误:GET请求不需要携带
Content-Type: application/json请求头,且Accept头未优先声明接收JSON格式响应 - 未自动跟进Cookie校验流程:你没有基于首次返回的Cookie自动发起二次请求,自然拿不到业务数据
- 开启了响应头输出:
CURLOPT_HEADER=true会把响应头和业务内容混合输出,无法直接解析JSON
修复方案
调整后的完整代码
<?php $urlx = "https://www.tmdn.org/tmview/api/trademark/detail/AR500000003159511"; echo $urlx."<hr>"; $lurl = getTMview($urlx); function getTMview($url) { $agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:92.0) Gecko/20100101 Firefox/92.0"; // 临时Cookie文件路径,确保目录有读写权限 $cookieFile = tempnam(sys_get_temp_dir(), 'tmview_cookie'); try { $request_headers = [ 'Accept: application/json,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Referer: https://www.tmdn.org/tmview/' ]; $curl = curl_init(); curl_setopt($curl, CURLOPT_AUTOREFERER, true); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curl, CURLOPT_COOKIESESSION, true); curl_setopt($curl, CURLOPT_COOKIEJAR, $cookieFile); curl_setopt($curl, CURLOPT_COOKIEFILE, $cookieFile); curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 2); curl_setopt($curl, CURLOPT_DNS_USE_GLOBAL_CACHE, false); curl_setopt($curl, CURLOPT_ENCODING, ""); curl_setopt($curl, CURLOPT_FAILONERROR, true); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_FORBID_REUSE, true); curl_setopt($curl, CURLOPT_HEADER, false); // 关闭响应头输出,直接拿响应体 curl_setopt($curl, CURLOPT_HTTPGET, true); curl_setopt($curl, CURLOPT_HTTPHEADER, $request_headers); curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_setopt($curl, CURLOPT_MAXREDIRS, 20); curl_setopt($curl, CURLOPT_NOBODY, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_BINARYTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_TIMEOUT, 10); // 超时调为10秒 curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, $agent); curl_setopt($curl, CURLPROTO_HTTPS, true); // 第一次请求,获取校验Cookie curl_exec($curl); // 第二次请求,携带Cookie获取业务数据 $curl_response = curl_exec($curl); if ($curl_response === false) { throw new Exception(curl_error($curl), curl_errno($curl)); } curl_close($curl); // 删除临时Cookie文件 @unlink($cookieFile); $fileJSON = $curl_response; echo "<pre>"; print_r(json_decode($fileJSON, true)); // 直接解析JSON输出 } catch(Exception $e) { @unlink($cookieFile); trigger_error(sprintf('Curl falló con error: #%d: %s',$e->getCode(), $e->getMessage()),E_USER_ERROR); } } ?>
额外注意事项
- 确保Cookie文件保存的目录有读写权限,代码里用
sys_get_temp_dir()取系统临时目录,一般都有权限 - 不要频繁发起请求,该站点有频率限制,短时间请求过多会被IP封禁
- 如果还是拿不到内容,可以替换
User-Agent为你当前浏览器的真实UA,避免被反爬识别为爬虫
内容的提问来源于stack exchange,提问作者Chuguiman
相关产品推荐
相关产品推荐

