[xParser] 1.3.0 - Регулярные выражения + Кейс


Обработка регулярным выражением полученных данных доступна уже давно, благодаря такой сногсшибательной функциональности Fenom. А с версии 1.3.0 регулярки были внедрены:
а) в конфигурацию задания при указании записи селектора,
б) в поля источника.

Пользователю это даёт более гибкую выборку записей из источника. Под катом пример того, как я извращался при помощи регулярок в xParser.


Кейс


Дано

Возникла потребность распарсить сайт, имеющий странную структуру записей. На CSS или XPath синтаксисе к ним было не подобраться. Пример странной структуры:
<div class=content>
<p> 
<h2>Какой-то заголовок</h2>
Текст с описанием раздела
<p>
18.01.10 <a href="http://domain.zone/link1.html">Запись 1</a>
< br>Описание записи 1
<p>
24.12.09 <a href="http://domain.zone/link2.html">Запись 2</a>< br>
Описание записи 2
<p>
23.12.09 <a href="http://domain.zone/link3.html">Запись 3</a>
< br>Описание записи 3
<p>
22.12.09 <a href="http://domain.zone/link4.html">Запись 4</a>< br>
Описание записи 4
...
</div>
Я умышленно поставил пробел перед br, т.к. modx.pro съедал их.

Что мы имеем:
  1. Запись не содержится в отдельном контейнере. Отсюда сложность получить ее. Решаемо за счет регулярки!
  2. Теги p в каждой записи открыты, но не закрыты. Решается внутренними средствами xParser без вашего участия!
  3. Тег br может стоять, как сразу после ссылки, так и на следующей строке под ней. Решаемо за счет регулярки!
Версия xParser ниже 1.3.0 не решала такое, честно скажем…

Выборка записи

Как обычно, мы создаем задание. Только теперь при указании селектора записи в конфигурации задания, мы можем выбрать синтаксис, среди которых: CSS, XPath, RegExp. Нам нужны регулярные выражения!


Вот такую регулярку я составил для выборки записей из странной структуры:
/<p>\s?([0-9]{2}\.[0-9]{2}\.[0-9]{2}) <a href="([^"]+)">(.+)<\/a>\s?< br>\s?(.*)\s?<\/p>/ui
Я умышленно поставил пробел перед br, т.к. modx.pro съедал их.

Таким образом мы получим каждую запись на странице. Всего их было около 100 шт.

Поля источника

После чего нам надо распарсить поля источника. Это я тоже реализовал на регулярных выражениях:


Ссылка:
Синтаксис: RegExp
Ключ: link
Селектор:
/<a.*href="([^"]+)/ui

Дата:
Синтаксис: RegExp
Ключ: date
Селектор:
/<p>\s?([0-9]{2}\.[0-9]{2}\.[0-9]{2})/ui

Описание:
Синтаксис: RegExp
Ключ: description
Селектор:
/<p>\s?[0-9]{2}\.[0-9]{2}\.[0-9]{2} <a href="[^"]+">.+<\/a>\s?< br>\s?(.*)\s?<\/p>/ui
Я умышленно поставил пробел перед br, т.к. modx.pro съедал их.

Итого

С помощью регулярных выражений можно парсить даже самую сложную структуру. Поэтому всем советую изучать регулярки, хотя бы на том уровне, на котором знаю их я.
Дальше думаю сами разберетесь, что с этим всем делать… ;)

А ещё в прошлых версиях были добавлены классные функции:

  1. Указание кодировки страницы-источника,
  2. Переменная $_pls в параметры @INLINE чанка в системном поле, которая содержит массив значений, для получения нестандартных полей, например с двоеточием в ключе,
  3. Можно указывать скачивание медиа для конкретных полей, а не для всего задания в целом,
  4. Переписан метод xmlToArray на основе DOMDocument, что позволило парсить атрибуты у XML тегов, у которых указан контент. Контент теперь хранится в ключе массива @content, если у тега присутствуют атрибуты.
По последнему пункту: в связи с этим у некоторых пользователей могут слететь поля guid, которые указываются и с атрибутом, и с контентом внутри, одновременно. Для этого достаточно переписать получение этого поля на:
@INLINE {$guid['@content']}
Павел Гвоздь
17 февраля 2017, 05:13
modx.pro
2
2 860
+10
Поблагодарить автора Отправить деньги

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

Илья Уткин
17 февраля 2017, 09:37
0
Оффтоп…

У меня, вроде, br не съедаются:
<br>
    Павел Гвоздь
    17 февраля 2017, 10:46
    +2
    Что у тебя за br такой?))

    Вот:
    Вот тут будет тег:
    А тут текст после него...
      Илья Уткин
      17 февраля 2017, 10:48
      +3
        Василий Столейков
        17 февраля 2017, 15:21
        1
        0
        Да, мне тоже интересно, как ты его заставил отобразиться?
        Даже спецсимволы типа & lt; br & gt; съедаются…
          Василий Наумкин
          17 февраля 2017, 17:34
          +4
          Двойное кодирование не внутри тегов code и pre:
          &amp;lt;br>
          <br>
      Владимир
      17 февраля 2017, 09:58
      +1
      Как же это замечательно!
      PS Обновляться же безбоязненно можно? Не увидел что это версия до которой я и так успешно уже обновился.
      Спасибо!
        Nikita
        15 марта 2017, 18:39
        0
        Павел, добрый день!

        Вот тут у вас спрашивали, можно ли результаты парсинга сохрнять в TV.

        А можно ли результаты парсинга просто сохранять в бэк-энде, скажем как список в Tickets, но без создания собственно страниц/ресурсов сайта?
          Павел Гвоздь
          16 марта 2017, 07:44
          0
          Что за список в Tickets? В целом можно будет делать что угодно через плагин, просто он не нужен пользователям компонента, поэтому его ещё нет. По крайней мере заявки на его внедрение ещё не поступало.
            Nikita
            17 марта 2017, 17:30
            0
            Я имел ввиду списком внутри, в бэк-энде MODX, без создания страниц сайта.
          Алексей
          09 октября 2017, 17:25
          0
          Не понял как указать поле «link_attributes». В выпадающем списке не видно, да и пагинация почему-то не работает. (вторая страничка такая же как первая)
            Павел Гвоздь
            09 октября 2017, 18:46
            0
            Напишите в ТП на modstore, пжл.
              Алексей
              12 октября 2017, 13:58
              0
              Большое спасибо за обновление! Единственно не понял, как бороться с
              max_execution_time
              лимитом при парсинге даже около ~50 страниц это занимает больше обычных 60 секунд.
              link_attributes — нашел в файлике
              /core/components/xparser/processors/mgr/combo/getfields.class.php
              замечательную функцию:
              excludeResourceFields
              из которой закомментил
              // 'link_attributes',
              и все заработало!

              PS: также в новых версиях хотелось бы видеть функционал вырезки ненужного контента при парсинге.
            Impulse
            20 ноября 2017, 12:10
            0
            Всем привет! Настроил этот парсер, вроде нормально все, но при запуске пара секунд и всплывает окно
            Результаты парсинга:
            Заданий: 1
            Создано: 0
            Обновлено: 0
            Ошибок: 0
            Неудачный запусков: 1

            Из за чего не удачный запуск то?
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            14