Php / js - парсинг html - селектор не работает в php

Я использую библиотеку Simple HTML DOM на PHP, вы можете найти эту библиотеку здесь: Простой HTML DOM

Я также разбираю HTML с помощью Javascript, в основном, чтобы выделить нужные мне селекторы.

Я сначала экспериментирую с синтаксическим анализом с помощью Javascript (с querySelectorAll), и когда он работает, я повторно использую тот же селектор с PHP Simple HTML DOM (с -> find).

Давайте рассмотрим следующую страницу, чтобы проиллюстрировать проблему: Страница с Amazon.fr

$html = file_get_html('PAGE URL FROM EXAMPLE ABOVE');
$products = $html->find('.s-item-container');
for ($z = 0 ; $z < sizeof($products); $z++)
    {
        foreach($products[$z]->find('.a-row .a-spacing-none .s-access-detail-page') as $titles) 
            {
                $title = $titles->plaintext;
            }
    }

Это отлично работает, если я повторю $ title, я получу правильный заголовок.

Теперь, если я хочу фиксировать цены следующим образом:

$products[$z]->find('div > div.a-fixed-left-grid > div > div.a-fixed-left-grid-col.a-col-right > div:nth-child(2) > div.a-column.a-span7 > div.a-row.a-spacing-none > a > span.a-size-base.a-color-price.s-price.a-text-bold');

Если я отображу содержимое $ product [$ z], я вижу искомый селектор, он виден в html, но функция поиска его не находит.

Я пробовал то же самое в Javascript:

document.querySelectorAll('div > div.a-fixed-left-grid > div > div.a-fixed-left-grid-col.a-col-right > div:nth-child(2) > div.a-column.a-span7 > div.a-row.a-spacing-none > a > span.a-size-base.a-color-price.s-price.a-text-bold');

И он отлично работает, возвращая это:

enter image description here

Я не понимаю, почему это происходит, потому что, когда он работает в JS, он работает и в PHP, это единственный пример, когда он не работает, и я не вижу, что идет не так.

Есть ли у вас какие-либо идеи?

Спасибо ! Лоран

В соответствии с просьбой здесь ниже, вот дамп: (извините, трудно читать)

<div class="s-item-container"><div class="a-fixed-left-grid"><div class="a-fixed-left-grid-inner" style="padding-left:218px"><div class="a-fixed-left-grid-col a-col-left" style="width:218px;margin-left:-218px;float:left;"><div class="a-row"><div aria-hidden="true" class="a-column a-span12 a-text-center"><a class="a-link-normal a-text-normal" href="https://www.amazon.fr/MSI-GEFORCE-GTX-1060-3GT/dp/B01KHWOB78/ref=sr_1_18?ie=UTF8&amp;qid=1533908456&amp;sr=8-18&amp;keywords=GTX+1060"><img src="https://images-eu.ssl-images-amazon.com/images/I/518zhXqNWcL._AC_US218_.jpg" srcset="https://images-eu.ssl-images-amazon.com/images/I/518zhXqNWcL._AC_US218_.jpg 1x, https://images-eu.ssl-images-amazon.com/images/I/518zhXqNWcL._AC_US327_FMwebp_QL65_.jpg 1.5x, https://images-eu.ssl-images-amazon.com/images/I/518zhXqNWcL._AC_US436_FMwebp_QL65_.jpg 2x, https://images-eu.ssl-images-amazon.com/images/I/518zhXqNWcL._AC_US500_FMwebp_QL65_.jpg 2.2935x" width="218" height="218" alt="MSI GEFORCE GTX 1060 3GT OC Carte Graphique , 3 GB" class="s-access-image cfMarker" data-search-image-load></a><div class="a-section a-spacing-none a-text-center"></div></div></div></div><div class="a-fixed-left-grid-col a-col-right" style="padding-left:2%;float:left;"><div class="a-row a-spacing-small"><div class="a-row a-spacing-none"><a class="a-link-normal s-access-detail-page  s-color-twister-title-link a-text-normal" title="MSI GEFORCE GTX 1060 3GT OC Carte Graphique , 3 GB" href="https://www.amazon.fr/MSI-GEFORCE-GTX-1060-3GT/dp/B01KHWOB78/ref=sr_1_18?ie=UTF8&amp;qid=1533908456&amp;sr=8-18&amp;keywords=GTX+1060"><h2 data-attribute="MSI GEFORCE GTX 1060 3GT OC Carte Graphique , 3 GB" data-max-rows="0" class="a-size-medium s-inline  s-access-title  a-text-normal">MSI GEFORCE GTX 1060 3GT OC Carte Graphique , 3 GB</h2></a></div><div class="a-row a-spacing-none"><span class="a-size-small a-color-secondary">de </span><span class="a-size-small a-color-secondary">MSI</span></div></div><div class="a-row"><div class="a-column a-span7"><div class="a-row a-spacing-none"><a class="a-link-normal a-text-normal" href="https://www.amazon.fr/MSI-GEFORCE-GTX-1060-3GT/dp/B01KHWOB78/ref=sr_1_18?ie=UTF8&amp;qid=1533908456&amp;sr=8-18&amp;keywords=GTX+1060"><span class="a-size-small a-color-secondary"></span><span class="a-size-base a-color-price s-price a-text-bold">EUR 237,36</span></a><span class="a-letter-space"></span><span class="a-size-small a-color-secondary">+ EUR 14,90 Livraison</span></div><div class="a-row a-spacing-mini"><div class="a-row a-spacing-none"><span class="a-size-small a-color-price">Plus que 4 ex. Commandez vite !</span></div></div><div class="a-row a-spacing-mini"><div class="a-row a-spacing-none"><div class="a-row a-spacing-mini"></div><span class="a-size-small a-color-secondary">Autres vendeurs sur Amazon</span></div><div class="a-row a-spacing-none"><a class="a-size-small a-link-normal a-text-normal" href="https://www.amazon.fr/gp/offer-listing/B01KHWOB78/ref=sr_1_18_olp?ie=UTF8&amp;qid=1533908456&amp;sr=8-18&amp;keywords=GTX+1060"><span class="a-color-secondary a-text-strike"></span><span class="a-size-base a-color-price a-text-bold">EUR 176,54</span><span class="a-letter-space"></span>(28 d’occasion & neufs)</a></div></div></div><div class="a-column a-span5 a-span-last"><div class="a-row a-spacing-mini"><span name="B01KHWOB78">      <span class="a-declarative" data-action="a-popover" data-a-popover="{&quot;max-width&quot;:&quot;700&quot;,&quot;closeButton&quot;:&quot;false&quot;,&quot;position&quot;:&quot;triggerBottom&quot;,&quot;url&quot;:&quot;/review/widgets/average-customer-review/popover/ref=acr_search__popover?ie=UTF8&amp;asin=B01KHWOB78&amp;contextId=search&amp;ref=acr_search__popover&quot;}"><a href="javascript:void(0)" class="a-popover-trigger a-declarative"><i class="a-icon a-icon-star a-star-4"><span class="a-icon-alt">4,2 étoiles sur 5</span></i><i class="a-icon a-icon-popover"></i></a></span></span>    <a class="a-size-small a-link-normal a-text-normal" href="https://www.amazon.fr/MSI-GEFORCE-GTX-1060-3GT/dp/B01KHWOB78/ref=sr_1_18?ie=UTF8&amp;qid=1533908456&amp;sr=8-18&amp;keywords=GTX+1060#customerReviews">18</a></div><div class="a-row a-spacing-mini"><span class="a-size-small a-color-secondary a-text-bold">Descriptions du produit</span><br><span class="a-size-small a-color-secondary">... La carte graphique MSI GeForce <em>GTX 1060</em> 3GT OC met la VR (R&eacute;alit ...</span></div></div></div></div></div></div></div>

Так каков результат использования var_dump($products[$z]->find('REALLY LONG SELECTOR HERE'));?

Patrick Q 10.08.2018 16:36

Педантичное замечание - использование querySelector() на веб-странице, загруженной браузером, не является «синтаксическим анализом».

Sean Bright 10.08.2018 16:39

Возможно, используемая вами библиотека не поддерживает дочерний селектор >, см. это, вы можете это проверить? Может с простой находкой div > div

kip 10.08.2018 16:39

В первом примере есть дочерние селекторы, и это работает.

Laurent 10.08.2018 16:40

@Laurent Я имею в виду дочерний селектор >, как вы можете видеть здесь, а не селектор потомков, прочтите, пожалуйста, документ библиотеки в моем предыдущем комментарии

kip 10.08.2018 16:43

@PatrickQ Я добавил дамп в исходный пост, так как он был слишком большим, чтобы помещать его здесь. Как видите, селектор есть. Даже если я попытаюсь выбрать, например, только .s-price, он ничего не вернет с помощью -> find

Laurent 10.08.2018 16:44

Кип прав. Простая модель HTML DOM не поддерживает непосредственный дочерний селектор (>). См. этот вопрос, а также Вот этот

Patrick Q 10.08.2018 16:46

@kip div.product__sales-information> div> strong работает (на другой странице), что означает, что> поддерживается, но почему-то не работает все время

Laurent 10.08.2018 16:54

@Laurent Может появляться работать, но все будет зависеть от исходного HTML. Дело в том, что селектор не поддерживается. Готов поспорить, что на страницах, где это работает, вы получите тот же результат, если просто используете пробел вместо >.

Patrick Q 10.08.2018 16:56

Я предпочитаю этот библиотека, который поддерживает селекторы CSS2.1 и CSS3, но, возможно, он более сложен и огромен, попробуйте с пробелом, как сказал @PatrickQ

kip 10.08.2018 16:59

@PatrickQ Я попробовал, как предлагалось (если я вас хорошо понял), удалив все> и заменив пробелом, но проблема все еще остается. Я также заменил длинный селектор одним классом, но он тоже не сработал. Как будто в этом HTML есть что-то, что мешает синтаксическому анализу.

Laurent 10.08.2018 17:03

Вы меня плохо поняли. Я хочу сказать, что когда вы говорите «что означает, что > поддерживается, но почему-то не работает постоянно», вы ошибаетесь. На самом деле вы видите поведение, которое вы получаете при использовании пробела, но исходный HTML, вероятно, имеет только дочерний элемент один на этом уровне, что приводит к одинаковому поведению в обоих случаях. Я не говорю, что замена > пробелами даст вам результат что ты хочешь. Я говорю, что они выдадут результаты такой же, то есть доказательство, что и селектор >не поддерживается.

Patrick Q 10.08.2018 17:08

@PatrickQ Понятно, спасибо за объяснение. Другой пример, возможно, был чистой удачей. Нужно ли строго соблюдать иерархию или можно оставить пробелы в списке детей? До сих пор я строго следовал этому правилу, но это могло бы облегчить мою жизнь, если бы я не был обязан.

Laurent 10.08.2018 17:26

Я предлагаю вам прочитать комментарии и ответы на вопросы, на которые я указал выше, а также просмотреть другие результаты, которые вы получите, когда вы погуглите что-то вроде «дочернего селектора php simplehtmldom». Я действительно не могу ничего добавить, что еще не упоминалось в них. Я также предлагаю вам ознакомиться с библиотекой парсеров, предложенной выше Кипом, поскольку простой HTML DOM может не подходить для вас.

Patrick Q 10.08.2018 17:33
Эта библиотека - это замена, которая поддерживает все эти функции
pguardiario 11.08.2018 00:52
0
16
115
0

Другие вопросы по теме