[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
10 755
Поблагодарить автора Отправить деньги
Реклама

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

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

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

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

          Не нужно, чтобы компонент все эти действия делал, а нужна возможность управлять им в этой цепочке действий.
            Павел Гвоздь
            Павел Гвоздь Старожил
            03 февраля 2017, 10:43
            Скоро будут добавлены события на плагины, там будет возможность не только запустить свой код на определенном шаге парсинга, но и заменить окончательное действие парсера (добавление ресурса в базу) на свое, либо остановить парсинг текущей записи вовсе, отдав статус ошибки.
            Игорь
            Игорь Старожил
            16 февраля 2017, 02:54
            Для формирования XPath синтаксиса воспользовался XPath Helper для Google Chrome. В результате получил разный синтаксис. Например, вместо указанного в статье
            .//*[@class="title"]/*
            получил
            //*[@id="tickets-rows"]/div/div[1]/h3
            Каким образом можно получить верный XPath синтаксис для настройки xParser?
              Павел Гвоздь
              Павел Гвоздь Старожил
              16 февраля 2017, 07:55
              Пишите в ТП на modstore
              Александр
              Александр Старожил
              22 января 2018, 13:08
              Подскажите, этот компонент подойдет для парсинга XML такого вида?
              www.tss.ru/bitrix/catalog_export/yandex_800463.xml
                Павел Гвоздь
                Павел Гвоздь Старожил
                22 января 2018, 13:36
                Думаю, да!
                Базовый тег ленты: 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
                  Спасибо, сейчас проверю на тестовом. В целом этого должно хватить для дальнейшей работы. Осталось только разобраться, как создавать категории и подкатегории и можно покупать компонент.
                    Павел Гвоздь
                    Павел Гвоздь Старожил
                    23 января 2018, 22:04
                    В вашем XML есть, вроде, список категорий. Их парсинг также можно выставить отдельным заданием.
                Никита
                Никита Старожил
                23 января 2018, 19:05
                Добрый день! Скажем, я создаю агрегатор для других ресурсов, мне нужно автоматически собирать актуальные цены. Я смогу по селектору html элементов собирать нужные цены с других ресурсов и автоматически публиковать у себя на страницах?
                  Павел Гвоздь
                  Павел Гвоздь Старожил
                  23 января 2018, 22:04
                  Что за «другие ресурсы»?..
                    Никита
                    Никита Старожил
                    24 января 2018, 00:53
                    Другие сайты.
                    Например, у меня агрегатор кредитов от различных банков, нужно каждый день парсить актуальные данные с html страниц банков, ориентируясь по селекторам, собирать проценты, условия, и выводить в таблице сравнения.

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

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

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

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