如何解析节点属性?提取span内a标签href时遇函数调用报错
错误原因
报错Uncaught Error: Call to a member function getElementsByTagName()是因为你写了一行逻辑混乱的代码:
if( stripos($obj_div_flavor_span_each->getAttribute('class')->getElementsByTagName('a')->getAttribute('href'), 'flavor-title') !== false )
这里$obj_div_flavor_span_each->getAttribute('class')返回的是字符串类型的class属性值,你试图在字符串上调用DOM元素的方法getElementsByTagName(),这完全不成立,直接触发了错误。而且这行代码同时堆叠了判断class、获取a标签href的逻辑,语法和逻辑双重错误。
修正后的代码(基于原有遍历逻辑)
$sample_html = <<<HTML <div class="link-to-flavors"> <span class="flavor-banner"></span> <span class="flavor-space"></span> <span class="flavor-title"><span><a href="flavors.com/vanilla" class="flavor-link">Vanilla</a></span></span> <span class="flavor-price">$1.99</span> <span class="flavor-icons icons-inrow"></span> </div> <div class="link-to-flavors"> <span class="flavor-banner"></span> <span class="flavor-space"></span> <span class="flavor-title"><span><a href="flavors.com/strawberry" class="flavor-link">Strawberry</a></span></span> <span class="flavor-price">$2.99</span> <span class="flavor-icons icons-inrow"></span> </div> HTML; // 初始化DOMDocument @$dom = new DOMDocument(); // 屏蔽HTML解析警告 libxml_use_internal_errors(true); // 加载HTML内容 $dom->loadHTML($sample_html); $xpath = new DOMXPath($dom); $div_list = $xpath->query('//div[@class="link-to-flavors"]'); $result_array = []; if ($div_list->length > 0) { foreach ($div_list as $div_item) { $flavor_title = null; $flavor_link = null; $flavor_price = null; // 遍历当前div下的所有span $span_list = $div_item->getElementsByTagName('span'); foreach ($span_list as $span_item) { $span_class = $span_item->getAttribute('class'); // 处理标题和链接 if (stripos($span_class, 'flavor-title') !== false) { $flavor_title = trim($span_item->textContent); // 从当前span内部查找a标签,获取href $a_tag = $span_item->getElementsByTagName('a')->item(0); if ($a_tag) { $flavor_link = $a_tag->getAttribute('href'); } } // 处理价格 if (stripos($span_class, 'flavor-price') !== false) { $flavor_price = trim($span_item->textContent); } } $result_array[] = [ 'flavor_title' => $flavor_title, 'flavor_link' => $flavor_link, 'flavor_price' => $flavor_price ]; } } print_r($result_array);
更高效的XPath简化方案
既然已经用到XPath,完全可以直接定位目标元素,避免多层遍历:
$sample_html = <<<HTML <div class="link-to-flavors"> <span class="flavor-banner"></span> <span class="flavor-space"></span> <span class="flavor-title"><span><a href="flavors.com/vanilla" class="flavor-link">Vanilla</a></span></span> <span class="flavor-price">$1.99</span> <span class="flavor-icons icons-inrow"></span> </div> <div class="link-to-flavors"> <span class="flavor-banner"></span> <span class="flavor-space"></span> <span class="flavor-title"><span><a href="flavors.com/strawberry" class="flavor-link">Strawberry</a></span></span> <span class="flavor-price">$2.99</span> <span class="flavor-icons icons-inrow"></span> </div> HTML; @$dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML($sample_html); $xpath = new DOMXPath($dom); $div_list = $xpath->query('//div[@class="link-to-flavors"]'); $result_array = []; foreach ($div_list as $div_item) { // 直接通过XPath获取标题文本 $title_node = $xpath->query('.//span[contains(@class, "flavor-title")]/text()', $div_item)->item(0); $flavor_title = $title_node ? trim($title_node->nodeValue) : null; // 直接获取a标签的href属性 $link_node = $xpath->query('.//span[contains(@class, "flavor-title")]//a/@href', $div_item)->item(0); $flavor_link = $link_node ? $link_node->nodeValue : null; // 直接获取价格文本 $price_node = $xpath->query('.//span[contains(@class, "flavor-price")]/text()', $div_item)->item(0); $flavor_price = $price_node ? trim($price_node->nodeValue) : null; $result_array[] = [ 'flavor_title' => $flavor_title, 'flavor_link' => $flavor_link, 'flavor_price' => $flavor_price ]; } print_r($result_array);
核心修正要点
- 移除了字符串调用DOM方法的错误代码,
getAttribute('class')返回的是字符串,不能调用getElementsByTagName() - 匹配到
flavor-title的span后,再从该span内部查找a标签并获取href - 简化方案利用XPath相对查询,直接定位目标元素,代码更简洁且性能更优
内容的提问来源于stack exchange,提问作者Kermit
相关产品推荐
相关产品推荐

