PHP cURL与file_get_contents访问bartleby网站失败解决方案
问题原因
不存在网站专门针对PHP环境拦截的情况,请求被拦核心是你写的PHP代码发出去的请求和正常浏览器、本地Python发的请求特征差太多,触发了反爬规则:
- 多余配置:你加了
CURLOPT_CUSTOMREQUEST => 'GET',正常GET请求不需要单独自定义请求方法,这个配置会让cURL的请求特征出现明显异常,很容易被识别。 - 头格式错误:PHP cURL的
CURLOPT_HTTPHEADER参数要求传入的数组元素必须是头名: 头值格式的字符串,你写成了PHP关联数组的键=>值形式,实际发出去的请求根本没带上UA、authority这些核心头,服务器直接就能判定是异常爬虫请求。 - Cookie失效:你硬编码的Cookie是本地跑Python时从自己电脑请求里拿到的,这类站点的Cookie大多绑定请求IP、会话上下文,换到cPanel服务器的IP上直接就会失效,带失效Cookie请求很容易被拦截。
- 默认特征明显:你写的
file_get_contents版本连最基本的UA都没配置,请求头里会带明显的PHP流客户端标识,服务器直接返回503是正常结果。 - 环境差异:你本地跑Python用的是住宅IP,requests库的TLS握手特征、头排列顺序更接近真实浏览器,Cookie也是同IP下生成的合法会话,自然能正常拿到内容。
修正后的可用cURL代码
把之前的错误配置全部改掉,开启自动Cookie维护、自动跳转、压缩响应处理,代码可以直接在cPanel环境跑:
<?php $ch = curl_init(); $targetUrl = 'https://www.bartleby.com/questions-and-answers/1.-a-given-the-lines-l-7-124-tk-13k-1-k-3-and-l-x2-3s-y-1-10s-z-3-5s-determine-the-values-of-k-if-po/b88e3e3d-bfd6-4158-8335-6a3ca420430e'; curl_setopt($ch, CURLOPT_URL, $targetUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自动跟随301/302跳转 curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate, br'); // 自动处理压缩响应,不需要单独写Accept-Encoding头 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'authority: www.bartleby.com', 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-language: en-US,en;q=0.9', 'cache-control: max-age=0', 'sec-fetch-dest: document', 'sec-fetch-mode: navigate', 'sec-fetch-site: same-origin', 'sec-fetch-user: ?1', 'sec-gpc: 1', 'upgrade-insecure-requests: 1', 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.115 Safari/537.36', ]); // 自动维护Cookie,不要硬编码本地拿到的旧Cookie curl_setopt($ch, CURLOPT_COOKIEJAR, __DIR__.'/bartleby_cookie.txt'); curl_setopt($ch, CURLOPT_COOKIEFILE, __DIR__.'/bartleby_cookie.txt'); $response = curl_exec($ch); if(curl_errno($ch)){ echo '请求异常: ' . curl_error($ch); }else{ echo $response; } curl_close($ch);
注意要给代码同目录开启写入权限,用来存储自动生成的Cookie文件。
替代方案&避坑提示
- 如果原生cURL改完还是被拦截,可以用GuzzleHTTP库替代,它的默认请求行为更接近真实浏览器,请求特征更少,配置头和Cookie的逻辑也更简单,反爬场景下适配成本更低。
- 爬取场景下不要用
file_get_contents发请求,它的默认请求标识太明显,而且处理Cookie、跳转、重试的逻辑非常繁琐,基本一用就会被反爬系统识别。 - 如果改完代码还是返回403/404,先检查cPanel主机的出口IP是不是被站点标记了,大部分虚拟主机的IP因为之前被大量用来爬取数据,早就进了反爬系统的黑名单,这种情况换个正常的住宅代理IP就能解决。
- 请求频率不要太高,短时间内大量请求不管用什么客户端都会被拦截。
内容的提问来源于stack exchange,提问作者Ppap
相关产品推荐
相关产品推荐

