如何比file_get_contents更快获取页面并处理返回内容?
提速外部金融数据加载的实用方案
嘿,我看到你现在用file_get_contents抓取外部金融表格时加载慢到超过3秒,这事儿确实闹心。file_get_contents在处理外部HTTP请求时灵活性太差,换成cURL是个好起点,但还有几个关键优化点能帮你把速度拉上来,我给你一步步拆解:
1. 用cURL替代file_get_contents,灵活控制请求参数
file_get_contents默认没有合理的超时控制,也没法设置请求头模拟浏览器,很容易被目标网站限流或者陷入无限等待。cURL可以精准配置这些参数,还能复用连接,直接看代码替换:
// 初始化cURL会话 $ch = curl_init('https://exernalsite.com'); // 设置请求超时时间(比如5秒,避免长时间阻塞) curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 模拟浏览器请求头,降低被识别为爬虫的概率 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' ]); // 启用gzip压缩,减少传输的数据量 curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate'); // 要求返回结果而非直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 执行请求 $html = curl_exec($ch); // 处理请求错误 if(curl_errno($ch)) { $html = ''; // 可以替换为默认兜底内容 } curl_close($ch);
2. 加本地缓存,彻底减少外部请求次数
金融数据不会每秒都更新,缓存5-15分钟完全够用,这能直接砍掉90%以上的外部请求开销。这里给个简单的文件缓存示例:
// 缓存文件路径 $cacheFile = './finance_data_cache.html'; // 缓存有效期(比如10分钟,单位秒) $cacheExpire = 600; // 检查缓存是否有效 if(file_exists($cacheFile) && time() - filemtime($cacheFile) < $cacheExpire) { $html = file_get_contents($cacheFile); } else { // 把上面的cURL请求代码放在这里 // ...(cURL获取$html的逻辑) // 保存缓存(仅当请求成功时) if(!empty($html)) { file_put_contents($cacheFile, $html); } }
3. 优化DOM解析,减少不必要的节点遍历
你现在是先加载整个HTML,再逐层找table、tr,最后再过滤符合条件的行。可以直接用XPath精准定位目标节点,减少DOM处理的冗余操作:
$doc = new DOMDocument(); @$doc->loadhtml($html); $xpath = new DOMXPath($doc); // 直接用XPath过滤出需要的行:第二个table中,前6行且td数量>4的tr $rows = $xpath->query('//table[position()=2]/tr[position() < 6 and count(td) > 4]'); foreach($rows as $row) { $cells = $row->getElementsByTagName('td'); echo "<tr>\n"; // 直接遍历需要的列(跳过第4列) for($i = 1; $i < 6; $i++) { if ($i != 4) { echo "<td>" . $cells->item($i)->textContent . "</td>\n"; } } echo "</tr>\n"; }
4. 启用HTTP/2和连接复用(如果目标网站支持)
如果外部网站支持HTTP/2,开启cURL的HTTP/2协议能大幅减少连接握手时间,还能复用已有连接:
// 在cURL初始化后添加这几行 curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); // 允许复用连接 curl_setopt($ch, CURLOPT_FORBID_REUSE, false); curl_setopt($ch, CURLOPT_FRESH_CONNECT, false);
把这些优化点结合起来,加载速度应该能降到1秒以内(缓存命中时几乎瞬间加载)。如果之后还是有偶尔的延迟,再考虑添加加载动画div就好。
内容的提问来源于stack exchange,提问作者Dirty Bird Design
相关产品推荐
相关产品推荐

