2016-12-17 7 views
0

Я извлекаю html с сайта с file_get_contents. У меня есть таблица (с именем класса) внутри html, и я хочу получить данные внутри html-тегов.Получение элементов DOM из html от file_get_contents

Это, как я получать данные HTML из URL:

$url = 'http://example.com'; 
$content = file_get_contents($url); 

HTML, выглядит следующим образом:

<table class="space"> 
    <thead></thead> 
    <tbody> 
     <tr> 
     <td class="marsia">1</td> 
     <td class="mars"> 
      <div>Mars</div> 
     </td> 
     </tr> 
     <tr> 
     <td class="earthia">2</td> 
     <td class="earth"> 
      <div>Earth</div> 
     </td> 
     </tr> 
    </body> 
</table> 

Есть ли способ searh элементов DOM в PHP, как мы делаем в JQuery? Так что я могу получить доступ к значениям 1, 2 (первый td) и значению div во втором td.

Что-то вроде

а) поиск HTML для таблицы с именем класса пространства

б) внутри этой таблицы, внутри TBODY, возвратитесь каждая ТР «первое значение ТД» и «значение DIV внутри второго TD»

Так что я получаю; 1 и Марса, 2 и Земли.

+0

Используйте [DOMDocument] (http://php.net/manual/en/class.domdocument.php) для анализа HTML. – Barmar

ответ

0

Используйте, например, DOM extension. Класс DOMXPath особенно полезен для таких задач.

можно легко установить перечисленные условия с выражением XPath, например так:

//table[@class="space"]//tr[count(td) = 2]/td 

, где - //table[@class="space"] выбирает все элементы table из документа, имеющего class значения атрибута, равного "space" строки; - //tr[count(td) = 2] выбирает все tr элементы, имеющие ровно два td дочерние элементы; - /td представляет элементы td. Реализация

Пример:

$html = <<<'HTML' 
<table class="space"> 
    <thead></thead> 
    <tbody> 
     <tr> 
     <td class="marsia">1</td> 
     <td class="mars"> 
      <div>Mars</div> 
     </td> 
     </tr> 
     <tr> 
     <td class="earthia">2</td> 
     <td class="earth"> 
      <div>Earth</div> 
     </td> 
     </tr> 
     <tr> 
     <td class="earthia">3</td> 
     </tr> 
    </tbody> 
</table> 
HTML; 

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

$xpath = new DOMXPath($doc); 

$cells = $xpath->query('//table[@class="space"]//tr[count(td) = 2]/td'); 

$i = 0; 
foreach ($cells as $td) { 
    if (++$i % 2) { 
    $number = $td->nodeValue; 
    } else { 
    $planet = trim($td->textContent); 
    printf("%d: %s\n", $number, $planet); 
    } 
} 

Выход

1: Mars 
2: Earth 

Код выше должен рассматриваться как образец, а не инструкции для практического использования, как это не очень масштабируема. Логика связана с тем, что выражение XPath выбирает ровно две ячейки для каждой строки. На практике вы можете выбрать строки, перебирать их, и поставить дополнительные условия в петлю, например:

$rows = $xpath->query('//table[@class="space"]//tr'); 

foreach ($rows as $tr) { 
    $cells = $xpath->query('.//td', $tr); 

    if ($cells->length < 2) { 
    continue; 
    } 

    $number = $cells[0]->nodeValue; 
    $planet = trim($cells[1]->textContent); 
    printf("%d: %s\n", $number, $planet); 
} 

DOMXPath::query() вызывается с выражением XPath относительно текущей строки ($tr), затем проверяет если возвращенный DOMNodeList содержит как минимум две ячейки. Остальная часть кода тривиальна.


Вы также можете использовать SimpleXML расширение, которое также поддерживает XPath. Но расширение намного менее гибкое по сравнению с расширением DOM.

Для огромных документов используйте расширения на основе синтаксических анализаторов на основе SAX, таких как XMLReader.