[xParser] 1.6.3 События плагинов для кастомной логики и код ответа сервера


Пакет приобрёл 3 события плагинов и научился запоминать код ответа сервера при обращении к УРЛ.
Это круто по ряду причин:
  • Можно внедрить свою логику в процесс парсинга,
  • Можно совершать кастомные действия на сайте, в зависимости от получаемых данных при парсинге,
  • К примеру, если сервер отдал 301/302 редирект или 404 ошибку при обращении к УРЛу подзадания, то мы можем отключить этот ресурс с публикации вовсе.
  • Всё ограничивается вашей степенью извращённости фантазией!

Список событий плагинов


  • xParserOnBeforeTaskParse
    После получения данных страницы и разбора её на список статей для парсинга. Перед обработкой списка полей.
    Параметры:
    1. xParser $xp — экземпляр основного класса компонента,
    2. xpParser $parser — экземпляр класса парсера,
    3. array $task — массив задания,
    4. array $items — массив со списком необработанных статей,
    5. array $fields — массив со списком полей для обработки статей и получения необходимых данных.
     
  • xParserOnTaskItemParse
    После обработки списка полей. Перед получением данных из подзадания, если таковое есть.
    Параметры:
    1. xParser $xp — экземпляр основного класса компонента,
    2. xpParser $parser — экземпляр класса парсера,
    3. array $task — массив задания,
    4. string $item — строка с необработанным кодом статьи,
    5. array $row — массив с обработанными полями статьи.
     
  • xParserOnBeforeTaskActions
    После формирования списка статей с данными из подзаданий. Перед добавлением ресурсов.
    Пожалуй, самое интересное событие, т.к. позволяет менять данные у статей либо вообще остановить задание парсинга, ничего при этом не добавив.
    Параметры:
    1. xParser $xp — экземпляр основного класса компонента,
    2. xpParser $parser — экземпляр класса парсера,
    3. array $task — массив задания,
    4. array $rows — массив со списком обработанных статей.
     

Пара примеров


  1. Остановим парсер, ничего при этом не добавив.
    switch ($modx->event->name) {
        case 'xParserOnBeforeTaskActions':
            $modx->event->output('Не хочу это парсить!');
            break;
    }
     
  2. Отключим публикацию ресурса, если код ответа сервера был 301, 302, 404.
    $sp = &$scriptProperties;
    switch ($modx->event->name) {
        case 'xParserOnBeforeTaskActions':
            foreach ($sp['rows'] as &$row) {
                $resource = &$row['Resource'];
                // Если код ответа 301, 302, 404
                if (in_array($row['Request']['http_code'], array(301, 302, 404))) {
                    $resource['published'] = 0; // присвоим ресурсу published = 0
                }
            }
            unset($resource, $row);
            $modx->event->returnedValues = $sp; // передаём измененённые значения обратно
            break;
    }
     
P.S. За обновление благодарить Александра Чудинова!
Павел Гвоздь
25 июня 2018, 18:31
modx.pro
1
1 611
+3
Поблагодарить автора Отправить деньги

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

Андрей
25 июня 2018, 23:24
+1
Очень круто! Спасибо за обнову!
    Алексей
    02 октября 2018, 14:08
    0
    Как используя плагины, преобразовать корректно ответ сервера, имеется заголовок:
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=windows-1251
    ну и соответсвенно в распарсенных полях полный бардак с кодировкой русских букв
      Павел Гвоздь
      02 октября 2018, 16:20
      0
      Вам надо кодировку источника Windows-1251 конвертировать в UTF-8? Есть нативный функционал у xParser:
        Алексей
        03 октября 2018, 09:07
        0
        Всё увидел! всегда была настройка на виду, ведь -).
        Только если я ставлю windows-1251 ещё больше кракозябр появляется на месте русских букв (в 2-3 раза). Попробовал декодер лебедева, он мне написал что это CP-1251->UTF-8, и декодировал правильно.
        Все таки через плагин никак не поиграться с кодировкой?
          Павел Гвоздь
          03 октября 2018, 09:10
          0
          Через плагин можно думаю. Читайте доку.
          И почему не пишете в ТП Модстор? Там можно было бы скинуть доступы, я бы посмотрел в чем дело.
            Алексей
            03 октября 2018, 12:18
            +1
            Через ТП Модстор не получилось связаться, в итоге решил вот так:
            1. добавим модификатор феном iconv:
            $fenom->addModifier('iconv', function ($str,$to_encoding,$from_encoding ) {
                        return mb_convert_encoding($str, $to_encoding, $from_encoding);
                        //return iconv($in_charset, $out_charset, $str);
                    });
            2. в «Редакторе поля задания» в строке «Поле в источнике» используем fenom для преобразования кодировки распарсенного поля при записи его в поле modResource, в примере поле modReource.pagetitle:
            @INLINE {$pagetitle|iconv:'CP1251':'utf-8'}
            3. Всё. При этом не очень удобно просматривать поля в «Списке данных источника» – потому как они отображаются кракозябрами.
            PS: видимо у меня сайт для парсинга попался какой-то уникальный, потому как настройка «Кодировка страницы» в окошке «Редактировать HTML задание» не решала вопрос – все русские буквы всё равно были не читаемы.
            PSS: похоже события плагинов xparser'а не работают на процессор mgr/field/test при проверке полей, только при создании ресурса.
      Konstantin
      11 февраля 2019, 08:08
      0
      А как можно пропускать элемент по условию? Ну то есть, если импортируем товары из прайса, и у каждого есть поле stock со значением 0 или 1?.. Пробовал через феном типа
      {if $stock == '1'}
          1
      {else}
      {/if}
      и в настройках поля ставил галочку «Поле должно быть обязательно заполнено», думая, что если поле пустое из-за того что $stock = 0, то парсер просто пропустит этот элемент и пойдет дальше. Но нет :-(
        Павел Гвоздь
        11 февраля 2019, 11:57
        +1
        Думаю, примерно так:
        $sp = &$scriptProperties;
        switch ($modx->event->name) {
            case 'xParserOnBeforeTaskActions':
                foreach ($sp['rows'] as &$row) {
                    $row['Resource'] = [];
                }
                unset($row);
                $modx->event->returnedValues = ['rows' => $sp['rows']];
                break;
        }
        Sergey (Sentinel)
        29 марта 2019, 18:00
        0
        Как правильно настроить парсер товаров для miniShop2?
        делаю на тестовом, подробной инструкции нет, та что есть не работает
          tuk33vl
          tuk33vl
          23 июня 2019, 12:34
          0
          Добрый день.
          Отличное обновление, как раз вовремя.
          Нам нужно на этапе парсинга, когда все данные с 2 заданий (основное и подзадание) собраны, применить некие изменения по нашей логике.
          Вся логика работает, а вот как передать эти измененные даные далее — не пойму.
          Взяли из примера вашего такую команду, но она не сработала у нас
          $modx->event->returnedValues = $sp;
          Плагин пишем на событие xParserOnBeforeTaskActions
            Павел Гвоздь
            23 июня 2019, 16:50
            0
            Внимательнее изучите код плагина. Массив $sp сам по себе не появится.
              tuk33vl
              tuk33vl
              23 июня 2019, 20:16
              0
              Спасибо, разобрались. А можно ли пропустить ресурс при парсинге по условию?
              $modx->event->output('Не хочу это парсить!');
              Это как мы поняли вообще останавливает задание, а нужно пропустить текущий и перейти к следующему ресурсу, по условию.
                Павел Гвоздь
                24 июня 2019, 08:16
                0
                Вырезать его из массива.
                  tuk33vl
                  tuk33vl
                  24 июня 2019, 08:58
                  0
                  Посмотрите пожалуйста, наш плагин, что-то не пропускает ресурс по условию((
                  <?php
                  $sp = &$scriptProperties;
                  switch ($modx->event->name) {
                  	case 'xParserOnBeforeTaskActions':
                  	
                          foreach ($sp['rows'] as &$row) {
                              $resource = &$row['Resource'];
                              $html = $resource['content'];
                  			
                  			$brand = getPropValueFromHtmlByName($html, 'Brand');
                  			
                          }
                          // Пропускаем ресурс по условию - бренд
                    		if ($brand != 'Samsung') {
                  			$row['Resource'] = [];
                    		}
                  		unset($resource, $row);
                          $modx->event->returnedValues = $sp;
                          break;
                  }
                    Павел Гвоздь
                    24 июня 2019, 09:50
                    0
                    У вас кривой код…
                      tuk33vl
                      tuk33vl
                      24 июня 2019, 09:59
                      0
                      Подскажите пожалуйста, как исправить, почему тут всегда нужно вымаливать помощь?
                        Павел Гвоздь
                        24 июня 2019, 10:05
                        0
                        Может, потому что я не вызывался писать код за вас? К тому-же, если вы пишете на PHP, то должны наверное понимать, что делаете?
                        P.S. У данного компонента есть Техподдержка в Modstore, там я могу помочь с таким небольшим куском кода.
                          tuk33vl
                          tuk33vl
                          24 июня 2019, 10:07
                          -2
                          Все ясно с этим сообществом. Неужели трудно указать на строку или строки где неверно. нет мы будет отписки тут писать и в ТП отправлять
                            Павел Гвоздь
                            24 июня 2019, 10:09
                            0
                            А я вот не уверен, что вы покупали данный компонент. Возможно вы где-то его скачали, поэтому не вижу смысла оказывать здесь техническую поддержку.
                              tuk33vl
                              tuk33vl
                              24 июня 2019, 10:13
                              -2
                              Ох уж эта меркантильность во всем и везде… насколько мне известно, сейчас все компоненты защищены от установки и скачивания.
                              Да и мы просим вас не решить задачу целиком, а лишь помочь в ее решении, ведь вы наверняка видите в чем проблема, просто вы не хотите помогать — так скажите это прямо, а не завуалированно про покупки и прочие вещи.
                              Павел Гвоздь
                              24 июня 2019, 10:21
                              +2
                              сейчас все компоненты защищены от установки и скачивания
                              Вы ошибаетесь.

                              вы не хотите помогать — так скажите это прямо
                              Я сам решу, как мне это говорить, прямо или криво. Не надо указывать мне, что делать и как это делать.
                              И видимо мои слова «я не вызывался писать код за вас» это завуалировано, ок…

                              вы наверняка видите в чем проблема
                              Я уже написал в чём проблема:
                              У вас кривой код…
                              если вы пишете на PHP, то должны наверное понимать, что делаете
                              P.S. Попробуйте работать с записями в цикле… И это $row['Resource'] = []; не есть «вырезать».
                              tuk33vl
                              tuk33vl
                              24 июня 2019, 10:48
                              0
                              И это $row['Resource'] = []; не есть «вырезать».
                              Да, я так понял нужно unset делать.
                              Подскажите что означают эти 2 строки, ведь unset делается в любом случае…
                              unset($resource, $row);
                              $modx->event->returnedValues = $sp;
                            Василий Наумкин
                            24 июня 2019, 10:36
                            +3
                            Поддержка платных дополнений оказывается там же, где они покупаются — в магазине.

                            Не надо гнать на сообщество, общайтесь с автором в специально придуманном для этого месте.
                              tuk33vl
                              tuk33vl
                              24 июня 2019, 10:46
                              -4
                              О, Бог вылез из норки…
                              А это место для чего придумано? Чтобы здесь помощь получить или восхвалять затянувшиеся на 10 лет работы по MODX 3?
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          24