[xParser] 1.2.0 - Парсер HTML контента + совмещение заданий

Парсер HTML контента востребованная штука, поэтому естественным шагом было его внедрение в xParser.

А с версии 1.2.0 компонент позволяет совмещать задания. Например, вам нужно распарсить RSS ленту и каждую запись выпилить с сайта полностью. Для этого:
  1. Создаётся пара заданий (первое — RSS, второе — HTML),
  2. Настраивается,
  3. Запускается.

Подробнее об HTML парсере


Так как в RSS ленте у нас по-умолчанию присутствует некий массив полей, которые можно распределить по полям MODX, то в HTML дела обстоят несколько сложнее: нам нужно самим создать эти поля, указав селектор до каждого из них.
Давайте на примере MODX.pro рассмотрим, как это делается:

Добавляем задания


Покажу пример, в котором происходит запуск одного задания из другого. Для этого нам надо будет создать 2 задания:

Добавляем primary задание

Primary заданием я называю список новостей, которые нам необходимо распарсить.
Жмём Добавить => Добавить HTML задание.
На вкладке Основное заполняем примерно так:


Переключаемся на вкладку Конфигурация, где указываем:
  • Селектор записи (пока только CSS-подобный синтаксис),
  • С какой по счёту записи стартовать,
  • Сколько записей парсить,
  • Шаблон для создаваемых ресурсов,
  • Контекст,
  • Родительский контейнер в пределах выбранного контекста,
  • Скачивать ли медиа-контент.


Жмём Сохранить — задание добавлено!

Добавляем secondary задание

Secondary заданием я называю задание с настройкой парсинга для полной статьи. Его мы будем указывать в качестве наследника для первого задания.
Жмём Добавить => Добавить HTML задание.
На вкладке Основное заполняем примерно так:

Важно указать:
  • URL — ссылку на какую-нибудь статью с modx.pro (потребуется для настройки полей источника),
  • Поставить галочку Является подзадачей.
Переключаемся на вкладку Конфигурация, где указываем:
  • Селектор записи: #content

Настройка источника


Так как задания у нас типа HTML, то придётся вручную создавать данные источника, которые будем парсить. Потребуется сделать это также, для двух заданий. Жмём на задании правой мышью => Источник.

Настройка источника для primary задания

Здесь достаточно добавить всего 1 поле — ссылку на полную версию статьи. Однако, я предлагаю добавить ещё и поле content, в котором будет храниться вступительная часть статьи. В этом вступительном тексте также указывается основное изображение статьи, вот его то мы и будем выдирать с помощью регулярки. Происходить это будет на шаге Настройки полей primary задания. Жмём Добавить.

Здесь у нас есть возможность указать CSS-подобный или XPath синтаксис. Для разных полей часто требуется и тот, и другой.

Внимание: XPath синтаксис имеет неприятный баг: не понимает названия тегов, поэтому приходится указывать тег, как *

Заполняем примерно так:



Там же можно проверить, насколько корректно парсер получает указанные нами значения. Для этого требуется нажать на кнопку с глазом:


Настройка источника для secondary задания

Тут я добавил также 2 поля: pagetitle и content.

Pagetitle:
Синтаксис: CSS
Ключ: pagetitle
Селектор: h3.page-title

Content:
Синтаксис: CSS
Ключ: content
Селектор: .page-content

Настройка полей задания


По большому счёту тут всё очень похоже на настройку RSS задания, т.к. у нас уже есть данные из источника, которые можно просмотреть в виде распечатанного массива, кликнув по кнопке Массив сырых значений. Сейчас нам надо, опираясь на эти ключи и значения источника, правильно добавить поля для парсинга. Жмём на задании правой мышью => Поля.

Описывать подробно возможности пакета на данном этапе не буду, кому интересно, может почитать это в описании настройки RSS заданий.

Настройки полей primary задания

Здесь тоже достаточно одного поля — link, но мы добавим и поле с основным изображением поста. Выдернем это изображение из вступительной части статьи с помощью Fenom и регулярного выражения. Жмём Добавить.

Link:
Системное поле: пусто
Поле в источнике: link
Значение по-умолчанию: пусто

Introtext: (запишем сюда изображение)
Системное поле: Resource.introtext
Поле в источнике:
@INLINE {$content | preg_get : '!https?://.+\.(?:jpe?g|png|gif)!Ui'}
Значение по-умолчанию: пусто

Теперь в таблице добавленных полей задания у поля link кликаем на звезду (поле должно стать оранжевым) и на соседнюю кнопку. Откроется окошко добавления связанного задания. Там есть сноска, продублирую:
1) Убедитесь, что выбранное поле действительно является ссылкой.
2) При парсинге эта ссылка будет передана в задание, которое вы выбрали ниже.
3) Из выбранного задания будут получены все поля для создания объекта.
4) Полученные поля перезапишут аналогичные поля из текущего задания.

В поле Принимающее задание выбираем MODX.pro (Secondary). Таким образом, текущее задание (Primary) передаст УРЛ из поля link в задание (Secondary). Жмём Сохранить. Поле link в таблице подсветится синим цветом:


Настройки полей secondary задания

Тут добавляем 3 поля: pagetitle, content и published.

Pagetitle:
Системное поле: Resource.pagetitle
Поле в источнике:
@INLINE {$pagetitle | preg_replace : '! \<sup class.*!ui'}
Значение по-умолчанию: пусто

Content:
Системное поле: Resource.content
Поле в источнике: content
Значение по-умолчанию: пусто

Published:
Системное поле: Resource.published
Поле в источнике: пусто
Значение по-умолчанию: 1

Итого


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

P.S.: Следующим шагом будет внедрение возможности путешествия по страницам.

P.P.S.: Компонент успешно вырос из логотипа, надеюсь modstore заметит это. :)
Павел Гвоздь
15 января 2017, 01:18
modx.pro
9
8 419
+17
Поблагодарить автора Отправить деньги

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

Владимир
15 января 2017, 10:06
+1
Круто! Спасибо, Павел!
    Дмитрий Иванов
    15 января 2017, 14:18
    +1
    А через прокси умеет ходить на сайты?
      Павел Гвоздь
      15 января 2017, 17:55
      +1
      Пока нет, но и это в планах: авторизация на сайте перед парсингом, вход через прокси.
        Антон
        Антон
        15 января 2017, 19:50
        0
        Можно стену вконтакта парсить?
          Павел Гвоздь
          16 января 2017, 22:13
          +2
          Скорее да, чем нет. :) Не проверял подобное. Если интересно — могу позже проверить и отписаться.
      brioni
      16 января 2017, 00:53
      0
      Мало создать компонент, нужно еще научить им пользоваться. У Павла отлично получается и первое и второе.
      Но, кроме этого, хорошей мотивацией к покупке дополнения (для меня точно) станет публикация кейсов (практической выгоды — трафика на сайт) от использования ХParser.
        Владимир
        16 января 2017, 10:00
        +2
        Извини, научить заработать при помощи какого то инструмента — это уже чья то отдельная работа, разве нет? А ты предлагаешь что бы тебе в стоимость ПО добавили не только документацию, а «публикация кейсов (практической выгоды — трафика на сайт) » и мотивировали тебя тем самым купить. Честно, прочел, аж обалдел. Это инструмент, у него много способов применения, и, наверно логично что бы пользователи делились опытом и кейсами.

          brioni
          16 января 2017, 14:01
          -4
          Я лишь высказал свое мнение, адресованное не только автору дополнения, но и всем кто его прочитает. С него (мнения) можно «обалдеть», а можно принять к сведению…
          Павел Гвоздь
          16 января 2017, 22:17
          +3
          Как уже правильно заметил Владимир: я продаю лишь инструмент, а что с ним делать — ваша забота. Парсер можно использовать для совершенно разных целей.
          Евгений Шеронов
          03 февраля 2017, 09:08
          0
          Можно ли с помощью этого компонента реализовать подобное?

          В ресурсе в ТВ или в любых других полях, хранятся ссылки, к примеру 3.
          Запуск по крону раз в день парсинга этих ссылок для каждого ресурса.
          Промежуточные результаты парсинга нужных полей (для простоты будет по 1 полю для источника, то есть ещё 3 тв или других полей) записываются в эти 3 поля.
          И по окончанию парсинга ссылок каждого ресурса запускается сниппет, который уже будет обрабатывать промежуточные результаты.

          Не нужно, чтобы компонент все эти действия делал, а нужна возможность управлять им в этой цепочке действий.
            Павел Гвоздь
            03 февраля 2017, 10:43
            +1
            Скоро будут добавлены события на плагины, там будет возможность не только запустить свой код на определенном шаге парсинга, но и заменить окончательное действие парсера (добавление ресурса в базу) на свое, либо остановить парсинг текущей записи вовсе, отдав статус ошибки.
            Игорь
            16 февраля 2017, 02:54
            0
            Для формирования XPath синтаксиса воспользовался XPath Helper для Google Chrome. В результате получил разный синтаксис. Например, вместо указанного в статье
            .//*[@class="title"]/*
            получил
            //*[@id="tickets-rows"]/div/div[1]/h3
            Каким образом можно получить верный XPath синтаксис для настройки xParser?
            Александр
            22 января 2018, 13:08
            0
            Подскажите, этот компонент подойдет для парсинга XML такого вида?
            www.tss.ru/bitrix/catalog_export/yandex_800463.xml
              Павел Гвоздь
              22 января 2018, 13:36
              0
              Думаю, да!
              Базовый тег ленты: offers
              Базовый тег записи: offer
              Вот что получаем в качестве данных записи:
              Array
              (
                  [url] => http://www.tss.ru/catalog/elektrostantsii/dizelnye_elektrostantsii/tss_deutz/dizelnyy_generator_tss_ad_25s_t400_1rm6_006533/
                  [price] => 574770
                  [currencyId] => RUB
                  [categoryId] => 156198
                  [picture] => Array
                      (
                          [0] => http://www.tss.ru/upload/iblock/963/96345baa8c9803081a7eda6b50d2ff29.jpeg
                          [1] => http://www.tss.ru/upload/iblock/bbe/bbe36c018fe04464b4cdc4c1abc3a5cd.jpeg
                          [2] => http://www.tss.ru/upload/iblock/103/10383a412da94c070450fb80dda8ef38.jpeg
                          [3] => http://www.tss.ru/upload/iblock/27a/27a143c97fe28b09a6f96d22b11c5b1d.jpeg
                      )
              
                  [name] => Дизельный генератор ТСС АД-25С-Т400-1РМ6
                  [description] => Дизель-генератор TSS Deutz номинальной мощностью 25 кВт (31,2 кВА) предназначен для обеспечения электропитания объектов электроснабжения как в качестве основного, так и в ка...
                  [param] => Array
                      (
                          [0] => Array
                              (
                                  [@content] => <p><b>Дизель-генератор TSS Deutz ...
                                  [name] => Полное описание
                              )
              
                          [1] => Array
                              (
                                  [@content] => 24
                                  [name] => Гарантия, срок (мес)
                              )
              
                          [2] => Array
                              (
                                  [@content] => 400/230
                                  [name] => Напряжение (В)
                              )
              
                          [3] => Array
                              (
                                  [@content] => 006533
                                  [name] => Артикул
                              )
              
                      )
              
                  [id] => 2181526
                  [available] => true
              )
              Я заведомо сократил список параметров, т.к. получалась простыня. Также убрал весь код из параметра «Полное описание»…

              Дальше эти данные можно обработать при помощи Fenom и вставить в нужные поля в MODX.
                Александр
                23 января 2018, 18:29
                0
                Спасибо, сейчас проверю на тестовом. В целом этого должно хватить для дальнейшей работы. Осталось только разобраться, как создавать категории и подкатегории и можно покупать компонент.
                  Павел Гвоздь
                  23 января 2018, 22:04
                  0
                  В вашем XML есть, вроде, список категорий. Их парсинг также можно выставить отдельным заданием.
              Никита
              23 января 2018, 19:05
              0
              Добрый день! Скажем, я создаю агрегатор для других ресурсов, мне нужно автоматически собирать актуальные цены. Я смогу по селектору html элементов собирать нужные цены с других ресурсов и автоматически публиковать у себя на страницах?
                Павел Гвоздь
                23 января 2018, 22:04
                +1
                Что за «другие ресурсы»?..
                  Никита
                  24 января 2018, 00:53
                  0
                  Другие сайты.
                  Например, у меня агрегатор кредитов от различных банков, нужно каждый день парсить актуальные данные с html страниц банков, ориентируясь по селекторам, собирать проценты, условия, и выводить в таблице сравнения.

                  Или агрегатор квартир в Москве, каждый день парсить сайты застройщиков, получая из нужного селектора html актуальные цены, количество оставшихся страниц и так далее
                    Павел Гвоздь
                    24 января 2018, 01:42
                    +1
                    Теоретически можно, на практике надо ближе знакомиться с задачей.
                      Никита
                      24 января 2018, 14:25
                      0
                      Если на практике, то можно спарсить с другого сайта определённую строку, ориентируясь по селектору, применить к ней регулярные выражения, сохранить в какой-нибудь таблице бэкенда и от туда уже брать данные на фронтента?
                        Павел Гвоздь
                        24 января 2018, 19:15
                        +1
                        Увы, сейчас пока нельзя работать с кастомными объектами.
                          Никита
                          24 января 2018, 19:24
                          0
                          Это планируется в будущем реализовать?
                MODXyou
                09 февраля 2018, 12:15
                0
                Добрый день! Подскажите Ваше дополнение modstore.pro/packages/import-and-export/xparser может ли парсить YML файлы? Если да то каким это будет выглядить образом? Спасибо!
                  Павел Гвоздь
                  12 февраля 2018, 10:58
                  0
                  Увы, YML парсить не умеет. Можно внедрить, но смысла пока не вижу в этом.
                  Ольга
                  26 февраля 2018, 14:12
                  +1
                  Павел, можно ли автоматически создавать и удалять товары minishop2? сохранять фото, характеристики? заказчик хочет периодически синхронизироваться с сайтами поставщиков, удаляя не найденные товары и добавляя новые.
                    Павел Гвоздь
                    26 февраля 2018, 21:31
                    0
                    Удалять — нет. Остальное — да.
                      Ольга
                      28 февраля 2018, 15:53
                      0
                      А обновлять на существующие товары цены?
                        Павел Гвоздь
                        28 февраля 2018, 17:44
                        0
                        Обновлять товары можно, если они созданы парсером. Дело в том, что парсеру для обновления ресурса/товара нужно внедрить уникальный ID.
                    Sergey (Sentinel)
                    13 марта 2019, 19:29
                    0
                    Есть задача парсить каталог товаров с опциями для minishop2
                    Скажите, какие условия должны быть у сайта с которого парсим?
                      Павел Гвоздь
                      13 марта 2019, 21:45
                      0
                      Нужно, чтобы товары были доступны в коде сайта. Вообще, можете потестировать на modhost.pro.
                      eflit
                      22 августа 2019, 23:27
                      0
                      Здравствуйте, подскажите такой вопрос допустим парсим товары с сайта поставщика возможно ли будет вставить остатки в поле от компонента msOptionsPrice2?
                        Павел Гвоздь
                        23 августа 2019, 06:44
                        0
                        Там можно навесить плагин на каждую строку парсинга, вот так можно будет. Из коробки работа с msop не предусмотрена.
                          eflit
                          23 августа 2019, 11:00
                          0
                          Понял в общем решить возможно. Спасибо.
                        Сергей
                        02 сентября 2019, 15:55
                        0
                        Здравствуйте, как добавить в парсинг XML:
                        carcopy.ru/export/integration_site/66803_1VSD.xml
                          Павел Гвоздь
                          02 сентября 2019, 15:56
                          0
                          Как RSS. Остальные вопросы пишите в ТП на Modstore.
                          Евгений
                          22 марта 2020, 21:13
                          0
                          Хочу приобрести компонент, но при тестировании не смог понять можно ли обновлять при парсинге уже созданные до парсинга ресурсы в minishop2. Например:

                          1. Есть ресурс с артикулом 1102 (был создан вручную)
                          2. Есть xml файл с полем model и значением 1102, а также полем price со значением 100
                          3. В настройках парсера у поля model ставлю звездочку, делая его уникальным полем

                          Если я запускаю парсер и убираю галку в поле «Создавать новые записи» (Скрин yadi.sk/i/n4BheOzy_V5GQg), то после запуска вижу, что обновлено 0 ресурсов.

                          Я что-то делаю не так или парсер не может обновлять уже существующие ресурсы в minishop?
                            Павел Гвоздь
                            23 марта 2020, 10:51
                            0
                            Там есть галка «Обновлять».
                              Павел Гвоздь
                              23 марта 2020, 10:53
                              0
                              А, тьфу, вижу:
                              был создан вручную
                              Так это не работает, обновляются только записи созданные парсером.
                                Евгений
                                30 марта 2020, 22:03
                                0
                                Планируется ли доработка, чтобы можно было обновлять созданные вручную ресурсы? Если да, то можете хотя бы примерно по срокам сказать?
                              eflit
                              19 декабря 2020, 12:27
                              0
                              Подскажите если имею такую структуру
                              <div class="chairs_page_list">
                              <a href="/">
                              товар 1
                              </a>
                              <a href="/">
                              товар 2
                              </a>
                              ....
                              </div>
                              Как мне правильно записать селектор записи для основного задания и парсить ссылку для подчиненного?
                                Павел
                                01 января 2024, 19:50
                                0
                                Не могли бы вы поделиться решением?
                                Даниил
                                03 января 2022, 13:42
                                -1
                                А вот как бы получить xParser бесплатно?? Нужен ппц просто, а с деньгами ну совсем плохо, даже на еду нехватает, последний бичпакет вот утром догрыз. Может кто нибудь поделится, пожалуйста
                                ewal
                                09 февраля 2022, 21:39
                                0
                                Скажите пожалуйста, парсер умеет работать с ресурсами редита, если страница источника перекрывается подтверждением 18+ где надо нажать на кнопку yes. Так же источник это reddit.com. И еще вопрос, вы реализовали возможность парсера чтобы он переходил по страницам сайта для дальнейшего парсинга?
                                  Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                  46