ThinkPHP里用
发带代理的请求,关键不是换IP,而是绕过目标反爬校验
很多短视频平台(比如抖音、快手)返回的视频地址是带签名和时效性的,直接请求会
或跳转到错误页。单纯用
设个HTTP代理根本没用——它们校验的是
、
、
甚至
这类自定义头。
动态代理
只是辅助,核心得模拟真实浏览器行为。
实操建议:
立即学习
“
PHP免费学习笔记(深入)
”;
代理必须支持
隧道(即
方式),普通HTTP代理无法透传HTTPS请求头
务必复用
句柄,避免每次新建连接触发风控(尤其高频解析时)
代理IP要带地域信息(如江苏南京),部分平台会根据
和用户定位做一致性校验
别用免费代理池,99%的
或
都源于代理不稳定
正则匹配视频直链时,
容易漏掉JSON嵌套结构里的URL
现在主流平台基本把视频地址藏在
响应体里(比如抖音的
接口),而不是HTML源码中。用
这种粗暴写法,大概率匹配不到——因为
链接被包裹在多层引号、转义符、甚至Unicode编码里。
实操建议:
立即学习
“
PHP免费学习笔记(深入)
”;
先用
尝试解析整段响应,再逐层查
这类路径(抖音)、
(快手)
如果
失败,说明返回的是HTML或加密JS,这时才用正则,但得加
修饰符:
永远对提取出的URL做
和
,否则可能得到
这种编码串
ThinkPHP控制器里处理高并发解析请求,
必须禁用
TP默认配置下,
走的是PHP内置流封装器,不支持代理、超时精细控制,且无法设置
或复用连接。一旦并发上来,要么卡死,要么触发
超时,日志里全是
。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
实操建议:
立即学习
“
PHP免费学习笔记(深入)
”;
统一用
封装一个
方法,内部固定启用
和
(后者防连接复用导致的header污染)
在
里预设
资源,控制器方法里只调
,避免每次初始化开销
别在
里直接写业务逻辑,把解析流程拆成
→
→
三步,方便单独压测每环
去水印接口返回
重定向时,
的
会丢掉原始
有些平台返回的视频流是
跳转到CDN地址,而CDN响应头带
。如果直接用
,TP会强制覆盖为
,前端拿到的就是乱码或下载失败。
实操建议:
立即学习
“
PHP免费学习笔记(深入)
”;
改用
,但前提是确保
已通过
校验,防止
更稳妥的做法:用
获取CDN响应头,手动
透传
、
、
,再用
(注意内存限制)
如果CDN有防盗链(
白名单),必须在
请求时带上和原始页面一致的
,否则返回
真正难的不是写通接口,而是每次平台前端JS更新后,签名算法和请求头规则就变——你得盯着抓包工具里
面板的
和
栏,而不是只看文档。
cURL403curl_setopt($ch, CURLOPT_PROXY, ...)User-AgentRefererCookieX-SS-STUBHTTPSCONNECTcurl_init()IP归属地502 Bad GatewayConnection refusedpreg_matchJSONaweme/v1/web/aweme/detail/preg_match('/https?:\/\/[^"]+\.mp4/i', $html, $matches)mp4json_decode($response, true)video->play_addr->url_listitem->video->play_urljson_decodespreg_match('/"play_addr"\s*:\s*{"url_list"\s*:\s*\[([^]]+)]/s', $html, $m)urldecode()stripslashes()https%3A%2F%2F...%2Fvideo%2Fxxx.mp4file_get_contentsfile_get_contents('http://...')HTTP/2max_execution_timeOperation timed outcURLHttpHelper::request()CURLOPT_TCP_KEEPALIVECURLOPT_FORBID_REUSE__construct()curl_multi_init()curl_multi_add_handle()index()fetchRawData()extractVideoUrl()redirectVideo()302thinkphpredirect()Content-Type302Content-Type: video/mp4return redirect($url)text/htmlheader('Location: ' . $url); exit;$urlfilter_var($url, FILTER_VALIDATE_URL)Header InjectioncURLheader()Content-TypeContent-LengthAccept-Rangesecho file_get_contents($cdnUrl)ReferercURLReferer403NetworkHeadersPreview