PHP递归函数仅返回初始数据问题求助
解决PHP递归页面数据爬取只返回部分数据的问题
咱们先拆解下你遇到的两个版本的核心问题,再给出修复后的完整方案:
第一个版本的问题根源
你第一个递归函数里,递归调用得到的子页面数据完全没被合并!虽然递归过程中$ids在逐步累积,但最后返回的只是当前层级的$ids和$names,子递归收集的数据根本没被整合进来。另外外层遍历$urls时,每次都把$output重新赋值,最后只会保留最后一个URL的结果,前面的都被覆盖了。
第二个版本的问题根源
第二个版本里,你在递归时直接用$output = getMainPage(...)把当前的$output替换了,这就导致之前循环收集的ids和names被子递归的结果覆盖,最后只返回最后一次递归的数据。还有个低级错误:$output['$names']多了个美元符号,变量名写错了。
修正后的完整代码
我把这些问题都修复了,还补充了页面HTML的获取逻辑(你之前的代码里没写$html的来源,这会直接导致DOM加载失败):
<?php $urls = ['http://site1.com', 'http://site2.com']; $totalOutput = ['ids' => [], 'names' => [], 'listing_count' => 0]; // 遍历所有URL,合并每个URL的爬取结果 foreach ($urls as $url) { $pageOutput = getMainPage($url, $totalOutput['listing_count']); // 将单页结果合并到总结果中 $totalOutput['ids'] = array_merge($totalOutput['ids'], $pageOutput['ids']); $totalOutput['names'] = array_merge($totalOutput['names'], $pageOutput['names']); $totalOutput['listing_count'] += $pageOutput['listing_count']; } print_r($totalOutput); function getMainPage($url, $startingCount = 0) { // 先获取页面HTML(实际项目建议用curl替代file_get_contents,稳定性更高) $html = @file_get_contents($url); if (!$html) { return ['ids' => [], 'names' => [], 'listing_count' => 0]; } $dom = new DOMDocument; @$dom->loadHTML($html); $links = $dom->getElementsByTagName('a'); $ids = []; $names = []; $listingCount = $startingCount; foreach ($links as $link) { $href = $link->getAttribute('href'); // 这里替换成你实际提取$this_id和$this_name的逻辑 $this_id = // 比如从href或链接文本提取ID的代码 $this_name = $link->nodeValue; $ids[] = $this_id; $names[] = $this_name; $listingCount++; // 检测下一页链接,递归爬取 if (strpos($href, 'next') !== false) { // 处理相对路径,拼接完整的下一页URL $nextUrl = rtrim($url, '/') . '/' . ltrim($href, '/'); $nextPageOutput = getMainPage($nextUrl, $listingCount); // 合并递归返回的子页面数据 $ids = array_merge($ids, $nextPageOutput['ids']); $names = array_merge($names, $nextPageOutput['names']); $listingCount = $nextPageOutput['listing_count']; // 找到下一页后跳出当前循环(如果需要处理完当前页所有链接再爬下一页,可删除break) break; } } return [ 'ids' => $ids, 'names' => $names, 'listing_count' => $listingCount ]; } ?>
关键修复点
- 多URL结果合并:外层循环不再直接覆盖结果,而是把每个URL的爬取数据合并到总数组中。
- 递归数据整合:递归调用后,把子页面返回的
ids、names和计数合并到当前层级,而非直接替换。 - 变量错误修正:去掉了
$output['$names']的多余美元符号,补充了页面HTML的获取逻辑。 - 计数连续累积:把当前计数传递给递归函数,确保整个爬取过程的计数是连续递增的。
- 下一页逻辑优化:找到下一页后跳出当前循环,避免重复处理同一页面的其他链接(可根据需求调整)。
内容的提问来源于stack exchange,提问作者Judson Cooper
相关产品推荐
相关产品推荐

