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

如何通过PHP与DOMXPath正确分类DOM内容生成对应数组?

问题分析与解决方案

我来帮你搞定这个数组错位的问题!你现在遇到的核心问题是把所有<a>标签和所有<span>标签分别查询出来,然后通过数组下标$key强行关联——但你的HTML里有些<div class="classX">容器没有对应的<span>标签,导致<span>的数量比<a>少,下标自然就对应不上,才会出现后面的span_text乱匹配的情况。

正确思路:以容器为单位遍历

我们应该先获取所有的<div class="classX">容器,然后逐个处理每个容器内部的内容:每个容器里肯定有一个目标<a>标签,然后检查当前容器里是否存在对应的<span>标签,这样就能保证每个link_text和span_text是严格对应的。

修改后的PHP代码

$finder = new DomXPath($dom);
// 先获取所有class为classX的div容器,这是关键!
$divContainers = $finder->query("//div[contains(@class, normalize-space('classX'))]");

$data = [];
foreach ($divContainers as $container) {
    // 在当前div容器内查找目标a标签,使用.//限定查找范围为当前节点的子元素
    $linkNode = $finder->query(".//a[contains(@class, normalize-space('aClass'))]", $container)->item(0);
    $cleanLinkText = trim(str_replace("\n", " ", $linkNode->textContent));
    
    // 初始化当前项的数组,至少包含link_text
    $currentItem = [
        'link_text' => $cleanLinkText
    ];
    
    // 在当前div容器内查找对应的span下的p标签
    $spanTextNode = $finder->query(".//span[contains(@class, 'sClass')]/p", $container)->item(0);
    if ($spanTextNode) {
        $cleanSpanText = trim(str_replace("\n", " ", $spanTextNode->textContent));
        $currentItem['span_text'] = $cleanSpanText;
    }
    
    $data[] = $currentItem;
}

代码说明

  1. 以容器为单位遍历:先拿到所有的classX div,每个div是一个独立的单元,确保内部的a和span属于同一组。
  2. 限定查找范围:使用.//的XPath语法,意思是“在当前节点的后代元素中查找”,这样不会跑到其他div里去匹配元素。
  3. 按需添加span_text:每个div里先获取a标签的文本,再检查是否存在对应的span内容,有就添加span_text字段,没有就只保留link_text,完全符合你的需求。

验证结果

运行这段代码后,你就能得到期望的数组结构:

[
    ['link_text' => 'Link Text 1', 'span_text' => 'Text #1'],
    ['link_text' => 'Link Text 2'],
    ['link_text' => 'Link Text 3'],
    ['link_text' => 'Link Text 4', 'span_text' => 'Text #4'],
    ['link_text' => 'Link Text 5', 'span_text' => 'Text #5'],
]

内容的提问来源于stack exchange,提问作者Ricardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:14