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

PHP使用Goutte遍历DOM时如何选取指定p标签后的目标ul元素

解决方案

Goutte 底层基于 Symfony Crawler 组件,单纯靠基础CSS选择器无法精准定位「指定文本标签后紧邻的元素」,优先用XPath实现零误判的匹配,不会被页面其他位置的ul干扰。

推荐写法:XPath精准定位(容错率最高)

核心逻辑是先精准匹配到带目标标题的p标签,再取它紧邻的第一个同级ul节点,代码如下:

// XPath匹配规则:找到内部strong文本为目标标题的p标签,取它后面紧邻的第一个ul
$targetUlCrawler = $crawler->filterXPath('//p[strong[normalize-space(text())="Maladies fréquentes :"]]/following-sibling::ul[1]');

// 遍历目标ul下的所有li节点
$targetUlCrawler->filter('li')->each(function ($node) {
    if ($node->count() === 0) {
        return;
    }
    // 直接取当前li节点的文本即可,原代码中$node->filter('li')属于冗余写法
    $liText = str_replace('"', "'", trim($node->text()));
    // 执行你的数据库插入逻辑
});

XPath规则说明

  • normalize-space(text())会自动去掉文本前后的空白、换行,避免因页面排版的多余空格导致匹配失败
  • following-sibling::ul[1]只会取目标p节点之后的第一个同级ul,完全不会命中页面中其他位置的ul列表

原代码问题说明

你之前使用的.desc ul:first-of-type选择器,会匹配.desc容器下所有「作为父级第一个ul子元素」的节点,只要页面存在多个不同父级的ul,就会全部被选中,导致抓取到错误内容。另外你在遍历li的回调里写$node->filter('li')是冗余逻辑,因为each遍历的$node本身已经是li节点,直接调用$node->text()即可拿到内容。

备选CSS选择器写法(容错率低,不推荐)

如果不想用XPath,也可以通过节点遍历的方式找目标ul,但如果目标p和ul之间插入了其他节点(比如注释、空标签、广告位)就会匹配失败:

$targetUlCrawler = $crawler->filter('p > strong:contains("Maladies fréquentes :")')
    ->closest('p') // 向上找到strong外层的p标签
    ->nextAll() // 获取p后面的所有同级节点
    ->filter('ul')
    ->first(); // 取第一个ul节点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:57:21