Использование domxpath для анализа сложного вложенного HTML - PullRequest
0 голосов
/ 30 апреля 2018

У меня проблемы с выяснением того, как извлечь определенные элементы текста из довольно сложной HTML-страницы, чем любые другие примеры, которые я могу найти в Интернете.

Сайт, который я пытаюсь проанализировать, является веб-сайтом недвижимости, и в html они содержат такие вещи, как цена и статус объекта. Если мы возьмем в качестве примера состояние свойства, я попытаюсь получить «For Sale» из следующего фрагмента html:

<div class="repeating container of property details">
<div class="firstlevel other class too">
    <div class="secondlevel other class too">
        <div class="thirdlevel">
            <div class="fourthlevel">
                <span class="thisspan">For Sale</span>
                <span class="someotherspan">Something else</span>
            </div>
        </div>
    </div>
</div>

А затем с помощью следующего php я пытаюсь извлечь то, что мне нужно.

$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);

$properties = $xpath->query('//div[@class="repeating container of property details"]');

foreach($properties as $container) {

    $node = $xpath->query('div[@class="firstlevel other class too"]'
        . '/div[@class="secondlevel other class too"]'
        . '/div[@class="thirdlevel"]'
        . '/div[@class="fourthlevel"]'
        . '/span[@class="thisspan"]', $container); // returns a DOMNodeList  
    $result = $node->item(0)->value; // get the first node in the list which is a DOMAttr
    echo 'value: '.$result.'<br/>';
}

но я получаю следующую ошибку:

Undefined property: DOMElement::$value

Ясно, что он не выбирает то, что я пытаюсь достать, и больше ничего, что я пробовал до сих пор, похоже, не работает. Кто-нибудь может указать мне правильное направление?

1 Ответ

0 голосов
/ 06 июня 2018

Вы выбираете узел элемента (span), а не узел атрибута. Узлы элемента не имеют свойства $value. Используйте свойство $textContent:

$result = $node->item(0)->textContent;

Или вы приводите список узлов к строке в выражении Xpath:

$result = $xpath->evaluate('string(div[@class="firstlevel other class too"]'
    . '/div[@class="secondlevel other class too"]'
    . '/div[@class="thirdlevel"]'
    . '/div[@class="fourthlevel"]'
    . '/span[@class="thisspan"])', $container); // returns a DOMNodeList  
echo 'value: '.$result.'<br/>';

Это будет работать только с DOMXpath::evaluate(), DOMXpath::query() поддерживает только выражения, которые возвращают списки узлов.

...