PHP如何通过DOMDocument修改含new类的a标签href属性
问题根因
你的代码不生效的核心问题是用了错误的修改逻辑:你已经通过DOMDocument拿到了所有目标<a>标签的节点实例,完全没必要用字符串替换的方式修改$wikipediaInfoboxTable。字符串替换本身存在很多不可靠问题:如果多个a标签href值重复会错换、href带特殊转义字符会匹配失败,而且你当前的写法根本没有把DOM的修改同步到字符串变量里,自然不会有任何效果。
另外你用stripos匹配class的写法存在误判风险,比如类名是newest、renew的时候也会被判定为匹配,不符合只选带new类的要求。
正确实现代码
直接调用DOM节点原生的setAttribute方法修改href属性,所有修改完成后再从DOM对象导出目标信息框的HTML即可,参考代码:
libxml_use_internal_errors(true); $parser = new DOMDocument(); $parser->loadHTMLFile("待抓取的目标页面地址"); $allATags = $parser->getElementsByTagName("a"); foreach ($allATags as $aTag) { // 精确匹配new类,避免误匹配其他含new字符的类名 $classArr = preg_split('/\s+/', strtolower(trim($aTag->getAttribute('class')))); if (!in_array('new', $classArr)) { continue; } $term = trim($aTag->nodeValue); // 对搜索词做url编码,避免特殊字符破坏URL格式 $newHref = BASE_PATH . "search.php?term=" . urlencode($term) . "&type=sites"; // 直接修改当前节点的href属性,无需额外字符串替换 $aTag->setAttribute('href', $newHref); } // 所有修改完成后,提取目标信息框的HTML内容 // 注意:这里的选择逻辑根据你实际页面的信息框位置调整即可 $infoboxNode = null; foreach ($parser->getElementsByTagName('table') as $table) { if (str_contains($table->getAttribute('class'), 'infobox')) { $infoboxNode = $table; break; } } $wikipediaInfoboxTable = $parser->saveHTML($infoboxNode);
关键说明
- 操作DOM解析HTML时,优先用DOM提供的节点修改API,不要混用字符串替换,稳定性差很多
- URL拼接必须对动态参数做
urlencode处理,避免搜索词含空格、特殊符号时链接失效 - 类名匹配不要用字符串查找的方式,拆分为单独的类名项做精确匹配,避免误选
- 所有节点修改完成后再调用
saveHTML()导出目标节点内容,此时导出的就是已经完成所有替换的最终HTML
内容的提问来源于stack exchange,提问作者user7962781
相关产品推荐
相关产品推荐

