Сегодня я хочу поделиться с вами подробностями о новаторском инструменте для работы с данными - "Frog Parser", адрес проекта: https://frog-parser.com Этот инструмент представляет собой мощный парсер, который был разработан с целью сделать процесс извлечения данных из веб-сайтов максимально удобным, понятным и эффективным. Я постарался отойти от сложных парадигм программирования, делая данный инструмент доступным для пользователей с базовыми знаниями информатики, и в то же время удерживая гибкость и мощь необходимые для выполнения сложных задач парсинга.

"Frog Parser" основывается на проектном подходе, использует иерархические структуры команд и учитывает натуральное поведение пользователя при навигации по веб-страницам. В этой статье я хочу рассказать вам о ключевых особенностях этого продукта, его языке команд, типах представления рабочих документов, а также о преимуществах использования "Frog Parser" в ваших проектах. Давайте погрузимся в детали!

  1. Парсинг рассматривается как комплекс различных команд, объединенных в иерархические группы по смыслу, или workflow.

  2. С точки зрения конечного пользователя, процесс парсинга представляется в виде документа, именуемого "Frog Parser Workflow Document".

  3. Применяется проектный подход: документы группируются в проекты.

  4. Язык описания процесса парсинга, "Frog Parser Command Language", можно сравнить с языком ассемблера — это набор команд с параметрами.

  5. Документ "Frog Parser Workflow" может иметь различные представления: табличное, схематическое, текстовое.

  6. "Frog Parser Workflow Document" должен быть представлен в виде текстового человекопонятного файла для удобства хранения в системе контроля версий и ручного внесения правок.

  7. Язык команд "Frog Parser Command Language" должен быть простым и понятным для пользователя с базовыми знаниями информатики, при этом обеспечивая достаточную гибкость для выполнения задач, но не перегруженным сложными парадигмами из области программирования, распространенными среди профессиональных разработчиков.

  8. В результате процесса парсинга данных с веб-сайта создается "Dataset", который можно экспортировать из внутреннего представления в общепринятые форматы, такие как CSV или MS Excel.

  9. Взаимодействие с веб-страницей соответствует общепринятым в индустрии веб-разработки методам. Например, поиск элементов на странице возможен с помощью различных способов: по идентификатору, имени HTML-тега, имени атрибута HTML-элемента, CSS-классу, CSS-селектору.

  10. Навигация по веб-страницам имитирует поведение реального пользователя: клики по кнопкам, ввод данных в поля и т.д.

  11. Для работы с “Frog Parser” конечному пользователю не требуется установка дополнительного программного обеспечения — достаточно иметь доступ к Интернету и последнюю версию веб-браузера (Google Chrome, MS Edge).

  12. Задачи парсинга запускаются в пакетном режиме, а пользовательский интерфейс предусматривает мониторинг статуса их выполнения.

  13. Программный продукт “Frog Parser” доступен по подписке. В случае неактивной подписки, продукт работает в демонстрационном режиме, добавляя "водяные знаки" (Watermarks) в выходные данные."

Здесь для ознакомления приведены экранные копии “Frog Parser”.

Project list
Project list
Workflow list
Workflow list
Edit workflow as table, example example 1
Edit workflow as table, example example 1
Edit workflow as table, example example 2
Edit workflow as table, example example 2
Edit workflow as table, example example 3
Edit workflow as table, example example 3
Edit workflow a JSON
Edit workflow a JSON
Workflow execution details
Workflow execution details
Output dataset
Output dataset
Exported data to MS Excel
Exported data to MS Excel

Пример "Frog Parser Workflow Document". В данном случае осуществляется парсинг сайта созданного с использованием Ecommerce CMS Shopify: https://district-theme-demo.myshopify.com/collections/clothing

{
  "version": "1.0.0.0",
  "acceptLanguage": "",
  "commands": [
    {
      "@type": "SetConstantValueToVariableCommand",
      "enabled": true,
      "name": "set-implicitly-wait-variable-value",
      "description": "",
      "retryCount": 1,
      "variableType": "Long",
      "variable": {
        "name": "implicitly-wait"
      },
      "value": {
        "@type": "VariableValueLong",
        "value": 3000
      }
    },
    {
      "@type": "SetImplicitlyWaitCommand",
      "enabled": true,
      "name": "set-implicitly-wait",
      "description": "",
      "retryCount": 1,
      "variable": {
        "name": "implicitly-wait"
      }
    },
    {
      "@type": "CreateDatasetCommand",
      "enabled": true,
      "name": "create-dataset",
      "description": "",
      "retryCount": 1,
      "variable": {
        "name": "dataset"
      },
      "metadata": {
        "columns": [
          {
            "name": "page-number",
            "type": "Integer"
          },
          {
            "name": "product-title",
            "type": "String"
          },
          {
            "name": "product-price",
            "type": "String"
          }
        ]
      }
    },
    {
      "@type": "SetConstantValueToVariableCommand",
      "enabled": true,
      "name": "Set constant value to start-page variable",
      "description": "",
      "retryCount": 1,
      "variableType": "Url",
      "variable": {
        "name": "start-page"
      },
      "value": {
        "@type": "VariableValueUrl",
        "value": "https://district-theme-demo.myshopify.com/collections/clothing"
      }
    },
    {
      "@type": "OpenWebPageCommand",
      "enabled": true,
      "name": "Open start-web-page",
      "description": "",
      "retryCount": 1,
      "variable": {
        "name": "start-page"
      }
    },
    {
      "@type": "SetConstantValueToVariableCommand",
      "enabled": true,
      "name": "set-handle-current-page-to-true",
      "description": "",
      "retryCount": 1,
      "variableType": "Boolean",
      "variable": {
        "name": "handle-current-page"
      },
      "value": {
        "@type": "VariableValueBoolean",
        "value": true
      }
    },
    {
      "@type": "SetConstantValueToVariableCommand",
      "enabled": true,
      "name": "set-page-number",
      "description": "",
      "retryCount": 1,
      "variableType": "Integer",
      "variable": {
        "name": "page-number"
      },
      "value": {
        "@type": "VariableValueInteger",
        "value": 0
      }
    },
    {
      "@type": "WhileLoopCommand",
      "enabled": true,
      "name": "do-while-handle-current-page",
      "description": "",
      "retryCount": 1,
      "variable": {
        "name": "handle-current-page"
      },
      "commands": [
        {
          "@type": "IncrementVariableCommand",
          "enabled": true,
          "name": "increment-page-number",
          "description": "",
          "retryCount": 1,
          "variable": {
            "name": "page-number"
          }
        },
        {
          "@type": "FindElementsCommand",
          "enabled": true,
          "name": "find-product-card-elements",
          "description": "",
          "retryCount": 1,
          "findBy": {
            "@type": "FindByTagName",
            "value": "product-card"
          },
          "variable": {
            "name": "product-card-elements"
          }
        },
        {
          "@type": "ForAllLoopCommand",
          "enabled": true,
          "name": "for-all-product-cards",
          "description": "",
          "retryCount": 1,
          "variable": {
            "name": "product-card-elements"
          },
          "itemVariable": {
            "name": "product-card-element"
          },
          "commands": [
            {
              "@type": "FindChildElementCommand",
              "enabled": true,
              "name": "find-product-card-title-element",
              "description": "",
              "retryCount": 1,
              "findBy": {
                "@type": "FindByClassName",
                "value": "product-card__title"
              },
              "variable": {
                "name": "product-card-title-element"
              },
              "parentElementVariable": {
                "name": "product-card-element"
              }
            },
            {
              "@type": "ReadPropertyCommand",
              "enabled": true,
              "name": "read-product-card-title-element",
              "description": "",
              "retryCount": 1,
              "variable": {
                "name": "product-card-title-element"
              },
              "property": {
                "@type": "ElementPropertyText"
              },
              "newVariable": {
                "name": "product-card-title-text"
              }
            },
            {
              "@type": "FindChildElementCommand",
              "enabled": true,
              "name": "find-product-card-price-element",
              "description": "",
              "retryCount": 1,
              "findBy": {
                "@type": "FindByCssSelector",
                "value": ".price"
              },
              "variable": {
                "name": "product-card-price-element"
              },
              "parentElementVariable": {
                "name": "product-card-element"
              }
            },
            {
              "@type": "ReadPropertyCommand",
              "enabled": true,
              "name": "read-product-card-price-element",
              "description": "",
              "retryCount": 1,
              "variable": {
                "name": "product-card-price-element"
              },
              "property": {
                "@type": "ElementPropertyText"
              },
              "newVariable": {
                "name": "product-card-price-text"
              }
            },
            {
              "@type": "CreateDatasetRowCommand",
              "enabled": true,
              "name": "create-dataset-row",
              "description": "",
              "retryCount": 1,
              "variable": {
                "name": "dataset"
              },
              "columns": [
                {
                  "name": "page-number",
                  "columnVariable": {
                    "name": "page-number"
                  }
                },
                {
                  "name": "product-title",
                  "columnVariable": {
                    "name": "product-card-title-text"
                  }
                },
                {
                  "name": "product-price",
                  "columnVariable": {
                    "name": "product-card-price-text"
                  }
                }
              ]
            },
            {
              "@type": "SaveVariableCommand",
              "enabled": true,
              "name": "save-dataset",
              "description": "",
              "retryCount": 1,
              "variable": {
                "name": "dataset"
              }
            }
          ]
        },
        {
          "@type": "CheckElementExistsCommand",
          "enabled": true,
          "name": "check-next-page-link-exists",
          "description": "",
          "retryCount": 1,
          "findBy": {
            "@type": "FindByCssSelector",
            "value": "a[aria-label=\"Next page\"]"
          },
          "variable": {
            "name": "handle-current-page"
          }
        },
        {
          "@type": "IfThenCommand",
          "enabled": true,
          "name": "if-next-page-link-exists",
          "description": "",
          "retryCount": 1,
          "ifVariable": {
            "name": "handle-current-page"
          },
          "thenCommands": [
            {
              "@type": "FindElementCommand",
              "enabled": true,
              "name": "find-next-page-link-element",
              "description": "",
              "retryCount": 1,
              "findBy": {
                "@type": "FindByCssSelector",
                "value": "a[aria-label=\"Next page\"]"
              },
              "variable": {
                "name": "next-page-link-element"
              }
            },
            {
              "@type": "ClickCommand",
              "enabled": true,
              "name": "click-by-next-page-link",
              "description": "",
              "retryCount": 1,
              "variable": {
                "name": "next-page-link-element"
              },
              "clickIfInvisible": true
            }
          ]
        }
      ]
    }
  ]
}

Подводя итог, стоит отметить, что “Frog Parser” представляет собой уникальный инструмент, созданный для облегчения и упрощения процесса парсинга данных из веб-сайтов. Он объединяет в себе простоту использования для пользователей с базовыми знаниями информатики и мощность необходимую для выполнения сложных задач парсинга.

Используя “Frog Parser”, вы можете упростить и ускорить процесс извлечения данных, используя его интуитивно понятный язык команд, различные представления рабочих документов и возможность экспорта данных в общепринятые форматы. Кроме того, инструмент не требует установки дополнительного программного обеспечения и доступен по подписке, что обеспечивает максимальную гибкость использования.

В целом, "Frog Parser" предлагает универсальное и гибкое решение для работы с данными, сочетая в себе лучшие практики веб-разработки и навигации по страницам, имитируя поведение реального пользователя. Создан сбалансированный по простоте использования и функциональным возможностям нишевой программный продукт, следующий философии "Low Code Solution". Я надеюсь, что данный программный продукт поможет вам повысить эффективность и качество работы с данными.

Адрес проекта: https://frog-parser.com

Facebook страница проекта: https://www.facebook.com/frogparser

Telegram: https://t.me/frog_parser_com

С Уважением,

Роман

Комментарии (35)


  1. SWATOPLUS
    04.07.2023 00:53

    Вход через Гугл не работает.


    1. taluyev Автор
      04.07.2023 00:53

      Регистрация пользователя через гугл включает в себя шаг подтверждения емейла по приходящему токену. Это сделано для всех соц сетей, чтобы иметь в результате один пользовательский профайл сразу, а не объединять разные. Проверьте пожалуйста пнишло ли вам письмо с токеном. Затем введите значение токена в форму регистрации. После этого можно логиниться с помощью гугл аккаунта.


      1. SWATOPLUS
        04.07.2023 00:53
        +2

        Письмо пришло, токен ввел. Но не пускает. Пришлось воспользоваться кнопкой сбросить пароль и войти по логину и паролю.

        Но в любом случае. Вход через Гугл не должен присылать на почту, принадлежность почты и так подтверждается. А что касается объединения нескольких учеток, то их можно объединять по email. Вы перемудлили, там где не надо, а там где надо (интефс редактирования страниц/воркфловов не доделали).


        1. taluyev Автор
          04.07.2023 00:53

          "Вход через Гугл не должен присылать на почту, принадлежность почты и так подтверждается." - да, но: буквально вчера я вводил токен отправленный мне на гугловую почту гуглом работая с одним из сервисов гугл.


          1. taluyev Автор
            04.07.2023 00:53

            Это зависит от "точки зрения". Данная реализация позволяет привязать OAuth аккаунт к любому е-мейлу на данном сайте. Привязка осуществляется не по е-мейлу, а по идентификатору. Поэтому у пользователя запрашивается е-мейл, к которому пользователь собирается подключить OAuth аккаунт. Это то, что касается гугла. Касательно других OAuth провайдеров - никто не гарантирует, что пользователь скажем регистрировался на GitHub - Если вы доверяете ваш аккаунт OAuth провайдеру гугла, это не значит, что вы доверяете ваш аккаунт GitHub. Другой пользователь "теоретически" может зарегистрировать аккаунт на другом OAuth провайдере и далее зайти в ваш профиль уже на данном сайте. По этой причине токен высылается каждый раз, для всех OAuth провайдеров. Я понимаю, что гораздо удобнее для пользователя, когда его новый профайл создается совершенно прозрачно (и диалог кажется перегруженным, но есть и плюсы данного подхода), но в данном веб приложении пользователь согласно бизнес-логике веб приложения должен согласиться с лицензионным соглашением, поэтому это вынесено в один диалог. На практике предполагается, что это делается один раз, больше пользователь к данному диалогу не возвращается. Также обратите внимание, данное веб приложение позволяет "удалить" пароль. Следующая аутентификация будет возможна только через OAuth провайдера или через форму восстановления пароля пользователя. Возможно вам будет полезна эта информация, позволит вам взглянуть иначе на данную тему.


        1. taluyev Автор
          04.07.2023 00:53

          Пофиксил.


  1. Robastik
    04.07.2023 00:53
    +3

    Вообще, конечно, больше парсеров богу парсеров. Успехов и процветания.

    Однако, опыт сотен аналогичных проектов давно показал, что не взлетает, т.к. для мелких клиентов это совсем не лоукод, крупные предпочитают готовый датасет, а для прогеров это недоязыг и лучше бы обычный js например.


    1. taluyev Автор
      04.07.2023 00:53

      1) Мелкие клиенты могут заказать создание парсера на основе данного сервиса; 2) переиспользовать один из имеющихся для целевого маназина на рснове шаблона типа OpenCart, Shopify и других - пример доя шопифай приведен; 3) Можно создать набор команд для продвинутых пользователей включающих в себя интерпретатор языка программирования javascript - это впишется в архитектуру проекта.


      1. loginoffvich
        04.07.2023 00:53
        +1

        чегото мне показалось что мелкий клиент который в этом всём разберётся сможет самостоятельно всё это/parsing сделать ну или на крайняк пустить какой-нибдь вебsnake чтобы локально уже отдолбить собраное - незнаю кому надо это на регулярной основе чтобы не заниматься автоматизацией


        1. taluyev Автор
          04.07.2023 00:53

          Может. Можно купить хостинг и удаленно запускать скрипты через ssh, настроить cron, итд. Проекты подобные данному предполагают наличие документации, примеров.


      1. Robastik
        04.07.2023 00:53
        +1

        1) Мелкие клиенты могут заказать создание парсера на основе данного сервиса;

        Кому заказать? Тому, кто сам себе селениум? Зачем ему ваш SaaS? А для сына маминой подруги есть (десктопные бесплатные) продукты с визуальным программированием (или js - на выбор) того, что вы называете workflow.

        2) переиспользовать

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

        3) Можно создать набор команд для продвинутых пользователей включающих в себя интерпретатор языка программирования javascript

        И зачем продвинутым ваша прокладка к селениуму? Они и без вас гоняют его хоть в js, хоть в питоне.

        Ну реально же, сотни аналогичных сервисов. Чем ваш лучше?


        1. taluyev Автор
          04.07.2023 00:53

          Уникальность данного сервиса в выстроенном балансе между удобством и сложностью. Оценивать данный сервис стоит интегрированно: давать интегрированную оценку за и против. Зачем делать магазин на шаблоне если можно заказать у сына подруги самопис или зачем делать самопис, если можно взять готоввй магазин на основе шаблона - это подобная задача ввбора - всем находится место под Солнцем. В данном случае, стоит рассматривать данный сервис, как интегрированное программное решение. "Недоязык" - лучшая практика из "кровавого энтерпрайза". Процедурный подход из 70-х - лучше чем функционалтное программирование для подобного рода задач. Кесорю - Ксорево.


          1. SWATOPLUS
            04.07.2023 00:53

            Честно, я думал, что зайду и наклепаю простой парсер за пару минут. Но что-то не пошло. Слишком кривой ui. Например, зачем подтверждать создание объекта? Меня прям выбесило. Потом, после создания в него нужно зайти, что бы редактировать. Для POC нужен удобный интерфейс, а он совсем не удобный. Импорта/экспорта я не увидел там. Либо его нет, либо не нашёл из-за кривого интерфейса.


            1. taluyev Автор
              04.07.2023 00:53

              Да, на создание можно убрать подтверждение, после создания открывать на редактирование объект.


            1. taluyev Автор
              04.07.2023 00:53

              Импорта-экспорта нет (всего проекта) пока - потому, что это MVP. Но есть возможность сохрвнить исходный код Flow открыв его в виде json. Можно "всё" доделать, но выйти на рынок с седой бородой.


            1. taluyev Автор
              04.07.2023 00:53

              Поправил, как вы указали - для повышения удобства использования. Импорт-экспорт позже - это не 5 минут работы :)


              1. Pest85
                04.07.2023 00:53

                Это смотря на чем вы это писали. Если React/Angular + Redux то как раз 5 минут.


          1. Robastik
            04.07.2023 00:53

            балансе между удобством и сложностью

            Для кого? Неужели для

            "кровавого энтерпрайза" ?

            Сам ставлю на то, что нормальный офисный планктон хочет кнопку Сделать красиво и совсем не имеет времени и желания разбираться, учиться, отлаживать, поддерживать ..

            И ведь (говорят) хорошо идут готовые специализированные парсеры для shopify, amazon и т.п.


            1. taluyev Автор
              04.07.2023 00:53

              Подход работы с Workflow распространенный. Приведу пример. Всегда можно все сделать на хранимых процедурах, но клиенты выбирают SQL Server Integration Services, чтобы иметь "отраслевое решение". Другой пример, люди используют Wix, Tilda, Elementor, хотя существует Bootstrap 5, Tailwind, PrimeFlex. Инженеры склонны выбирать профессиональные инструменты для решения задач. Java бэкенд разработчики могут выбрать Vaadin, а не Angular или React для создания пользовательского интерфейса. Людям в деловых костюмах нравятся "стандартные", то есть шаблонные подходы к решению задач, когда решение задачи "испортить сложно", можно отдать проект на сопровождение другому специалисту. Это возможно благодаря "недоязыкам" - вставил картридж и все работает. Данный парсер может легко освоить ученик 10-го класса, который не является еще инженером программистом - это открывает для людей новые возможности, создаёт "АЙТИ для всех", а не только для инженеров, так как персональные компьютеры и мейнфреймы. Дети массово в школах изучают работу с офисными пакетами, но не Linux Console.


              1. Robastik
                04.07.2023 00:53

                создаёт "АЙТИ для всех"

                Создается впечатление, что вы не в курсе, что все это давно создано 100500 раз.

                Вот, например, школьники реально обожают. Но прочие перечисленные почему-то не пользуются)))


                1. taluyev Автор
                  04.07.2023 00:53

                  Когда я был "школьником" я смотрел в сторону "визуального редактора веб интерфейсов", сейчас предпочитаю верстать руками. Как объяснить всем пользователям, купившим Vaadin и MS SSIS, что есть лучшее решкние. Я понимаю, что двнная реализация не тянет на майкрософт интегрейшен сервис, но я один раз написал алгоритм копирования данных для одного из шаблонов Shopify и теперь этим могут пользоваться люди. Следующий алгоритм я сделаю для шаблона OpenCart и подробно опишу как он устроен и выложу в открытый доступ. Конечному пользователю может быть ближе и роднее слово "картридж" или "кассета", чем библиотеки Python.


                  1. Robastik
                    04.07.2023 00:53

                    может быть

                    Хорошо если угадали.


          1. ponikrf
            04.07.2023 00:53

            Не согласен, лучшие решения сочетают в себе 2 крайности, а не баланс. В целом сложно представить себе успешный парсер в виде сервиса. Мне кажется его можно сделать только на основе ИИ. Типа заходишь вместе с ним и объясняешь ему что нужно делать.


            1. taluyev Автор
              04.07.2023 00:53

              С этим конкретным проектом это покажет воля комьюнити и усилия затраченные на проект. Одну правку я уже внес, спасибо вам за рекомендации. Да, этот проект временный в перспективе развития возможностей искусственного интеллекта, как и многие другие программные продукты. Но кто-то должен тоже объяснить что и как нужно сделать...


              1. taluyev Автор
                04.07.2023 00:53

                deleted


              1. taluyev Автор
                04.07.2023 00:53

                deleted comment


  1. taluyev Автор
    04.07.2023 00:53

    deleted comment


  1. Pest85
    04.07.2023 00:53

    Что под капотом?
    Как обходите user-agent check?
    Используете несколько прокси?
    Как с captcha? Поддерживается?
    Antibot типа datadome.co обходите?


    1. taluyev Автор
      04.07.2023 00:53
      +1

      Под капотом работа через Selenium Web Driver. Парсер проверяет robots.txt и исходя из этого принимает решение о возможности продолжения работы. Обход капчи не планируется. Парсер союлюдает этикет работы в сети Интернет.


    1. taluyev Автор
      04.07.2023 00:53

      Сейчас прокси нет. Будут добавлены по мере развития проекта.


      1. Pest85
        04.07.2023 00:53
        +1

        Для чего вы планируете использовать прокси если
        >  Парсер союлюдает этикет работы в сети Интернет.


        1. taluyev Автор
          04.07.2023 00:53

          Для случая, когда для разных регионов посетителей веб ресурса сайт показывает разный контент. Но не запрещает вход по капче.


          1. Pest85
            04.07.2023 00:53

            Мне просто интересна ваша логика.

            Геоблок обходить этично, капчу и антиботов - нет. Где и как вы проводите черту?


            1. taluyev Автор
              04.07.2023 00:53

              Я не писал про обход геоблокировки. Я имел ввиду возможность посмотреть как выглядиь веб ресурс для разных регионов.


  1. Hidadmin
    04.07.2023 00:53
    +1

    Название сервиса созвучно с сеошным десктопным Screaming Frog SEO Spider, в котором также есть возможность извлечения данных.

    Полагаю, Фрог в названии это лишь случайное совпадение )

    Плюс, в аналогичном бесплатном SiteAnalyzer все это также есть с возможностью парсить через XPath, CSS, XQuery, Regexp.

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

    А для парсинга реально больших объемов сайтов я бы обратился в специализированные сервисы, коих достаточно. Из соображений надежности и чтобы не морочиться вручную с настройками и прочим.

    ИМХО

    + подписка в долларах. Ну такое себе. Вам бы для начала на русскоязычных юзверях откатать.
    + голый сервис без полноценного сайта и инфраструктуры - никто не найдет в поиске, соотв. с монетизацией будет сложнее, чем могло бы быть.

    В целом, идея наверное интересная, хотя тут нужно понимать рынок, и возможно что ниша давно занята аналогами, работающими в стиле - списался, дал им ТЗ, оплатил деньгу - они спарсили все что нужно и прислали готовый Excel, без танцев с бубном с настройками.