ThinkPHP抓取页面高频功能盘点:日常数据提效的5大核心用法【汇总】
ThinkPHP抓取页面五种方法:使用HTTP类发送GET请求并自动解码gzip获取网页源码;携带Cookie进行POST提交模拟登录;进行UTF-8转码并利用容错正则提取价格数据;使用collect库并发抓取多页列表提升效率;借助Filesystem类将HTML快照保存至本地storage目录便于分析。
ThinkPHP项目中快速提取网页结构化内容的5种实战方法:自动处理gzip的Http类GET请求、携带Cookie的POST提交、UTF-8转码+容错正则提取价格、collect并发抓取多页列表、Filesystem保存HTML快照。

想在ThinkPHP项目里快速提取网页标题、价格、列表数据等结构化内容,但卡在HTTP请求发不出、gzip解压失败、中文乱码或正则匹配不到?这篇文章直接给出5种能立刻跑通的实战用法,不讲原理只给可执行代码。
用Http类发GET请求并自动处理gzip
第一步:确保已安装think-http扩展(ThinkPHP 6.0+默认内置),无需额外require。
第二步:在控制器中调用Http::get(),它会自动识别并解压gzip/deflate编码的响应体:$response = Http::get('https://httpbin.org/gzip');
第三步:直接获取解压后的内容:$body = $response->getBody()->getContents();
注意:若目标网站强制返回gzip但Http类未自动解压,说明PHP缺少zlib扩展——执行php -m | grep zlib验证,缺失则需启用zlib.so。
POST提交表单并携带Cookie维持会话
方法一:使用withCookies()链式调用$response = Http::withCookies(['PHPSESSID' => 'abc123'])->post('https://example.com/login', ['username' => 'test', 'password' => '123']);
方法二:手动构造Cookie头(兼容旧版本)$response = Http::withHeaders(['Cookie' => 'PHPSESSID=abc123; user_token=xyz789'])->post('https://example.com/api/data', $data);
【务必检查Set-Cookie响应头是否被框架中间件拦截,如开启Session中间件,需确认session.driver配置为file或redis而非none】
用正则精准提取页面中的价格数字
第一步:先用mb_convert_encoding()将响应内容转为UTF-8,避免gbk网页出现乱码:$html = mb_convert_encoding($response->getBody()->getContents(), 'UTF-8', 'auto');
第二步:编写带中文容错的价格正则,匹配¥、$、¥等前缀及千分位逗号:$pattern = '/[¥$¥]\\s*([\\d,]+.?\\d*)/u';
第三步:执行匹配并清理逗号:if (preg_match($pattern, $html, $matches)) { $price = str_replace(',', '', $matches[1]); }
这一步不能跳过str_replace,否则数据库插入时会因逗号报错。
批量抓取多页列表并合并结果
① 定义基础URL模板:$base_url = 'https://example.com/list?page={page}';
② 构建页码范围数组:$pages = range(1, 5);
③ 使用collect()配合map并发请求(需开启Swoole协程或使用curl_multi):$results = collect($pages)->map(function($p) use ($base_url) { return Http::get(str_replace('{page}', $p, $base_url)); })->toArray();
④ 合并所有HTML并提取
$all_html = implode('', array_map(fn($r) => $r->getBody()->getContents(), $results));
$dom = new DOMDocument(); @$dom->loadHTML(mb_convert_encoding($all_html, 'UTF-8', 'auto'));
$xpath = new DOMXPath($dom);
$items = $xpath->query('//ul[@class="list"]/li');
抓取后保存HTML快照到本地storage目录
调用Filesystem::disk('public')->put()写入带时间戳的文件:
$filename = 'snapshots/' . date('Y-m-d') . '/' . md5($url) . '.html';
Filesystem::disk('public')->put($filename, $html);生成可访问URL时,必须拼接storage/app/public映射路径:
$url_path = str_replace('\\', '/', $filename);
return Filesystem::getDiskConfig('public', 'url') . '/' . $url_path;【部署前必须运行php think storage:link,否则/storage/snapshots/路径在浏览器中404】
