You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:53:33