#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 хотя в нем упоминаются только основные функции, под капотом находится гораздо больше