使用PHP Simple HTML DOM时出现多个属性问题


Problems with multiple attributes while using PHP Simple HTML DOM

我使用此代码来获取左侧导航栏的元素:

function parseInit($url) {
  $ch = curl_init();
  $timeout = 0;
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);     
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}
$data = parseInit("https://www.smile-dental.de/index.php");
$data = preg_replace('/<(d[ldt])( |>)/smi', '<div data-type="$1"$2', $data);
$data = preg_replace('/<'/d[ldt]>/smi', '</div>', $data);
$html = new simple_html_dom();
$html = $html->load($data);

但是面对这样的问题
例如,如果我使用这样的语法来获取元素:$html->find("div[data-type=dd].level2"),那么我将获得ALL具有数据属性DT、DD、DL和类名LEVEL2的元素。如果我使用另一种语法:$html->find("div.level2[data-type=dd]"),那么我得到ALL具有数据属性DD的元素,但具有类名LEVEL1、LEVEL2和LEVEL3等。你能解释一下问题出在哪里吗?提前感谢!

p.S.:所有DT、DL和DD元素都用regexp更改为具有适当数据属性的DIV元素,因为这个解析器错误地计算了这些元素的数量

REGXe不是用来操作HTML的,DOM解析器是。。。您正在使用的simple_html_dom可以很容易地做到这一点。。。

下面的代码会做你想做的很好(检查注释):

$data = parseInit("https://www.smile-dental.de/index.php");
// Create a DOM object
$html = new simple_html_dom();
$html = $html->load($data);
// Find all tags to replace
$nodes = $html->find('td, dd, dl');
// Loop through every node and make the wanted changes
foreach ($nodes as $key => $node) {
    // Get the original tag's name
    $originalTag = $node->tag;
    // Replace it with the new tag
    $node->tag = 'div';
    // Set a new attribute with the original tag's name
    $node->{'data-type'} = $originalTag;
}
// Clear DOM variable
$html->clear();
unset($html);

Here's is it in action

现在,对于多属性过滤,您可以使用以下任一方法:

foreach ( $html->find("div.level2") as $key => $node) {
    if (  $node->{'data-type'} == 'dt' ) {
        # code...
    }
}

OR(由h0tw1r3提供):

// array containing all the filtered nodes
$dts = array_filter($html->find('div.level2'), function($node){return $node->{'data-type'} == 'dt';});

请阅读手册了解更多详细信息。。。