PHP/DOM解析HTML:如何精准提取每个news项的标题与日期?
如何精准提取HTML中每个news项的标题和日期?
问题场景
我有如下HTML代码:
<div class="news"> <h3 class="border-bottom">Title 2</h3> <p class="mt-0 ml-1">2023-04-01</p> <img src="20230401.jpg" class="w-50 float-right ml-2"> <p class="lead"><p>Description 2</p></p> <a href="https://.../news/245" class="btn btn-secondary">Read more</a> </div> <div class="news"> <h3 class="border-bottom">Title 1</h3> <p class="mt-0 ml-1">2023-03-31</p> <img src="20230331.jpg" class="w-50 float-right ml-2"> <p class="lead"><p>Description 1</p></p> <a href="https://.../news/244" class="btn btn-secondary">Read more</a> </div>
我尝试用以下PHP代码提取每个news项的标题和日期:
$class = "news"; $dom = new DOMDocument(); $dom->loadHTML($html); $a = new DOMXPath($dom); $divs = $a->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $class ')]"); foreach ($divs as $link) { print_r($link->nodeValue); }
但输出了每个div下的全部文本内容:
Title 2
2023-04-01
Description 2
Read more
Title 1
2023-03-31
Description 1
Read more
需要实现精准提取标题和日期的需求。
解决方案
你可以在遍历每个news div时,通过XPath在当前节点范围内查询目标元素(h3标题和日期p标签),从而精准获取所需内容。修改后的代码如下:
$class = "news"; $dom = new DOMDocument(); // 忽略HTML解析中的警告,避免因不规范HTML报错 libxml_use_internal_errors(true); $dom->loadHTML($html); libxml_clear_errors(); $xpath = new DOMXPath($dom); // 定位所有class包含news的div元素 $newsDivs = $xpath->query("//div[contains(concat(' ', normalize-space(@class), ' '), ' $class ')]"); $newsItems = []; foreach ($newsDivs as $div) { // 在当前div下查询h3标题 $titleNode = $xpath->query(".//h3[@class='border-bottom']", $div)->item(0); // 在当前div下查询日期p标签 $dateNode = $xpath->query(".//p[@class='mt-0 ml-1']", $div)->item(0); if ($titleNode && $dateNode) { $newsItems[] = [ 'title' => trim($titleNode->nodeValue), 'date' => trim($dateNode->nodeValue) ]; } } // 输出结果 print_r($newsItems);
代码说明:
- 使用
libxml_use_internal_errors(true)忽略HTML解析时的警告,避免页面存在不规范HTML时导致解析失败。 - 在遍历每个news div时,XPath查询使用
.开头,表示仅在当前节点(即当前news div)范围内搜索,避免匹配到全局的h3或p标签。 - 通过
@class='xxx'精准定位目标元素,确保获取的是标题和日期对应的标签。 - 使用
trim()去除文本内容中的多余空格和换行符,让结果更整洁。
运行上述代码后,会得到结构化的结果:
Array ( [0] => Array ( [title] => Title 2 [date] => 2023-04-01 ) [1] => Array ( [title] => Title 1 [date] => 2023-03-31 ) )
内容的提问来源于stack exchange,提问作者Jibeji
相关产品推荐
相关产品推荐

