Простой анализатор HTML DOM — пропустить определенный элемент

#php #web-scraping

#php #очистка веб-страниц

Вопрос:

Я использую простой анализатор HTML DOM, и я хочу полностью игнорировать содержимое «вложенного» элемента и получить содержимое следующего элемента «pre».

 <div id=parent>

<div class="nested">
<pre>Text that I want ignored</pre>
</div>

<pre>
This is the text I want to access
</pre>
</div>
  

У меня нет контроля над исходным кодом HTML, и владелец недавно добавил «вложенный» элемент. Прежде чем я получил доступ к нужному мне контенту, я сделал это:

 $page_contents = file_get_html($url);    
$div_content = $page_contents->find('div[id=parent]pre', 0)->innertext;
  

Но, очевидно, новый вложенный элемент нарушил мой метод.

Кажется, я не могу найти никакой официальной документации относительно такого сценария.

Комментарии:

1. Хорошо, обновил свой ответ, где мог.

2. Почему бы вам не закодировать функцию, которая выполняет итерации среди дочерних элементов div с идентификатором «parent» и игнорирует дочерние элементы, которые не являются pre? Повторение, хотя эти дочерние элементы будут обходить «Текст, который я хочу игнорировать», потому что он не является дочерним элементом родительского идентификатора div, хотя они косвенно связаны.

Ответ №1:

не тестировалось, но попробуйте это

 $div_content = $page_contents->find('div[id=parent][class!=nested]pre', 0)->innertext;
  

или

 $div_content = $page_contents->find('div[id=parent class!=nested]pre', 0)->innertext;
  

или, может быть, даже только это, я думаю, что это действительно тот, но опять же, я не тестировал

 $div_content = $page_contents->find('div[class!=nested]pre', 1)->innertext;
  

все еще не знаю, сработает ли это, но попробуйте это

 $div_content = $page_contents->find('div[class!=nested pre]', 0)->innertext;
  

или

 $div_content = $page_contents->find('div[class!=nested pre]', 0)->plaintext;
  

Комментарии:

1. Хм, и первый, и третий возвращают «Текст, который я хочу игнорировать», в то время как второй возвращает ошибку.

2. @Nate Shoffner если вы измените 0 на 1, вы получите правильную вещь?

3. Я просто просматривал документацию, чтобы узнать, для чего предназначен этот параметр. И да, это работает. Вот что говорится в документации: «Find (N) th anchor, возвращает объект элемента или null, если не найден (на основе нуля)»

4. 3-й фрагмент — это тот, который сработал при изменении 2-го параметра на 1. Если вы обновите фрагмент, я приму ваш ответ. 🙂

5. @nate-shoffner отредактировал ответ, добавив некоторые другие вещи, чтобы попробовать тоже

Ответ №2:

find('div[id=parent] pre') находит все pre теги в указанных div и не заботится о том, заключен ли один из них в другой div , поэтому вот несколько предложений:

если вы точно знаете, какой pre вы хотите получить, просто укажите число, начинающееся с нуля, в вашем случае:

 $div_content = $page_contents->find('div[id=parent] pre', 1)->innertext;
  

в случае, если вы не знаете, сколько pre их существует, или не знаете порядок, вы можете просто удалить тот, который вам не нужен, а затем выполнить предыдущую строку, но на этот раз указав число 0:

 $page_contents->find('div[id=parent] div[id=nested] pre', 0)->outertext = '';
$div_content = $page_contents->find('div[id=parent] pre', 0)->innertext;
  

и в случае, если вы не хотите изменять $page_contents , просто назначьте своего родителя div временной переменной и сделайте, как описано выше:

 $temp = $page_contents->find('div[id=parent]', 0);
$temp->find('div[id=nested] pre', 0)->outertext='';
$div_content = $temp->find('pre', 0)->innertext;
  

конечно, есть много других способов сделать это, следует прочитать руководство http://simplehtmldom.sourceforge.net/manual.htm хотя в нем упоминаются только основные функции, под капотом находится гораздо больше