必须启用安全模式、配置国内镜像、安装必要扩展、禁用SSL校验并设置正确时区与Header——ThinkPHP 8.1抓取国内网站需绕过DNS污染、连接超时和SSL证书校验失败三重障碍,否则curl会卡死或返回空内容。

要在ThinkPHP 8.1项目中稳定抓取国内网站页面,必须绕过DNS污染、连接超时和SSL证书校验失败三重障碍,否则curl会卡死或返回空内容。
确认项目已启用安全模式并清空缓存
执行php think version,输出必须为【8.1.0】或更高版本;8.1.0-rc2、8.1.0-beta均不满足安全抓取前提。
编辑config/app.php,将'security_mode' => false改为true;该开关关闭时,框架允许动态调用file_get_contents等危险函数,攻击者可借爬虫入口注入任意URL。
删除runtime/cache/目录下全部文件——不清理会导致旧配置残留,security_mode实际未生效。
配置国内Composer镜像与PHP扩展
运行composer clear-cache清除本地源缓存,避免旧镜像残留干扰。
执行composer config -g repo.packagist https://mirrors.aliyun.com/composer/,强制全局使用阿里云镜像;不设镜像时,composer require guzzlehttp/guzzle常因packagist.org响应超时失败。
安装ext-curl和ext-openssl:Ubuntu系统执行sudo apt install php-curl php-openssl;CentOS执行yum install php-curl php-opcache。缺少openssl扩展会导致HTTPS页面抓取直接报cURL error 60。
抓取代码实现(含UA伪装与超时控制)
方法一:使用GuzzleHTTP(推荐)
执行composer require guzzlehttp/guzzle:7.8.1,指定7.8.1版本——该版本兼容PHP 8.1且已修复2026年3月曝出的DNS劫持漏洞。
在控制器中写入:
$client = new \GuzzleHttp\Client([<br> 'timeout' => 15,<br> 'verify' => false,<br> 'headers' => [<br> 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'<br> ]<br>]);<br>$res = $client->get('https://www.gov.cn/');<br>$html = (string)$res->getBody();
【'verify' => false不可省略】——国内部分政务站SSL证书由地方CA签发,PHP默认不信任,设为false才可成功握手;生产环境需替换为本地CA证书路径。
方法二:原生cURL(轻量备用)
创建app/common/HttpHelper.php:
function fetchPage($url) {<br> $ch = curl_init();<br> curl_setopt($ch, CURLOPT_URL, $url);<br> curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);<br> curl_setopt($ch, CURLOPT_TIMEOUT, 15);<br> curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);<br> curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1');<br> $content = curl_exec($ch);<br> curl_close($ch);<br> return $content;<br>}
调用:$html = fetchPage('https://www.12371.cn/');——使用iPhone UA可绕过部分党建网站的PC端反爬JS检测。
规避国内反爬的关键配置
第一步:在config/app.php中设置'default_timezone' => 'Asia/Shanghai',否则部分依赖时间戳的验证码接口会校验失败。
第二步:禁用ThinkPHP自动添加的X-Powered-By头,编辑app/middleware/TrustHost.php,在handle()开头加入header_remove('X-Powered-By');——某省级教育平台会根据该Header拦截非浏览器请求。
第三步:对目标域名做DNS预解析,在public/router.php顶部插入:
if (isset($_SERVER['HTTP_HOST']) && strpos($_SERVER['HTTP_HOST'], 'dzkbw.com') !== false) {<br> dns_get_record('dzkbw.com', DNS_A);<br>}
这一步能提前触发系统DNS缓存,避免抓取电子课本时因gethostbyname阻塞导致批量请求超时。
第四步:在config/template.php中强制关闭模板引擎执行能力,将'tpl_deny_php' => false改为true;否则若抓取内容被误传入view::fetch(),{php}标签可能被执行。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











