如何用cURL和preg_match_all抓取网页多行源码中的指定数值
解决跨多行匹配问题的两种方案
方案1:修正正则表达式(快速解决)
你的问题核心是默认正则模式下,.不会匹配换行符,导致跨多行的HTML结构抓不到。只需给正则加上s修饰符(PCRE_DOTALL),同时调整规则适配目标结构:
假设目标HTML结构类似:
<td>Averages</td> <td class="page_speed_123">82.84</td>
对应的PHP代码示例:
// $html是你通过cURL获取的网页内容 $pattern = '/<td>Averages<\/td>\s*<td class="page_speed_\d+">([\d.]+)<\/td>/s'; if (preg_match($pattern, $html, $matches)) { $averageValue = $matches[1]; echo "提取到的平均值:$averageValue"; } else { echo "未找到匹配内容"; }
\s*匹配任意空白(包括换行、空格、制表符),兼容HTML里的换行和缩进s修饰符让.匹配包括换行在内的所有字符,确保跨多行结构能被匹配[\d.]+精准匹配数字和小数点,只提取数值部分
方案2:用DOM解析(更可靠,推荐)
正则处理HTML容易因为结构微调失效,用DOMDocument+XPath是更专业的长期解决方案:
// 禁用HTML解析警告(避免网页不规范导致的报错) libxml_use_internal_errors(true); $dom = new DOMDocument(); $dom->loadHTML($html); // $html为cURL获取的内容 $xpath = new DOMXPath($dom); // 定位到包含"Averages"的<td,再取它的下一个class以page_speed_开头的<td> $nodes = $xpath->query('//td[text()="Averages"]/following-sibling::td[starts-with(@class, "page_speed_")]'); if ($nodes->length > 0) { $averageValue = trim($nodes->item(0)->nodeValue); echo "提取到的平均值:$averageValue"; } else { echo "未找到匹配内容"; } // 清除错误缓存 libxml_clear_errors();
这种方法不依赖具体换行格式,只要HTML的逻辑结构不变,就能稳定提取内容,适合需要长期维护的代码。
内容的提问来源于stack exchange,提问作者Ko1ind
相关产品推荐
相关产品推荐

