company_banner

Magic Tester. Как неподготовленный человек замечает ошибки, и как научить тому же робота

    Привет! Меня зовут Илья Кацев, и я представляю небольшое исследовательское подразделение в отделе тестирования в Яндексе. Вы уже могли читать о нашем экспериментальном проекте Роботестер — роботе, который умеет проделывать за тестировщика заметную часть рутинной работы.

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


    Есть такой тезис, сторонником которого я лично являюсь, — любую ошибку, которую может заметить неподготовленный пользователь, может обнаружить и робот. Именно это мы и попытались проверить. Но тут возникает вопрос: что именно человек считает ошибкой?

    Искусственный интеллект пока никто не изобрёл (хотя Хокинг, например, считает, что это к лучшему), но кое-каких успехов нам удалось добиться. В этом посте я расскажу о том, как мы формулировали опыт, которым обладают тестировщики-люди и постарались научить ему наших роботов, и что из этого вышло.

    Роботестер. Первый подход


    Когда мы создавали Роботестера, перед нами стояла задача автоматизировать рутинную работу, на которую уходит время тестировщика. Мы научили алгоритм открывать веб-страницу, понимать, какие действия можно произвести с элементами, заполнять текстовые поля, нажимать кнопки и пытаться угадать, когда же произошла ошибка. Но у нас возникла проблема — оказалось, что с высокой достоверностью робот может обнаружить только самые тривиальные ошибки.

    Дело в том, что принцип работы робота — проверять как можно больше страниц — приводил к большому числу тестов, а это означало, что точность определения ошибки становилась ключевым фактором. Мы подсчитали, что для проверки Яндекс.Маркета наш робот делал 800 000 различных проверок в сутки. Соответственно, если false positive rate проверок в среднем равен 0.001 (что кажется небольшим числом), то каждый день будет приходить отчет о якобы найденных 800 ошибках, которых на самом деле нет. Естественно, это никого не устраивает.

    Следует отметить, что «фальшивые» сообщения об ошибках всегда случаются. Особенно, когда речь идет о веб-тестах, так как для них используется вспомогательные инструменты — могут быть проблемы с браузером, который использует робот, проблемы с интернетом, и так далее.

    Есть весьма «чистые» проверки. Например, код ответа ссылки 404 с огромной вероятностью свидетельствует о том, что проблема есть. Пример проверки с низкой точностью — наличие в тексте буквосочетания « ,» (пробел и запятая). Действительно, когда между пробелом и запятой не подгрузились какие-то данные, такое буквосочетание свидетельствует об ошибках. Но иногда речь идет просто об опечатках. Особенно когда в область проверки попадает текст пользовательских комментариев или контенет из внешних источников. Поэтому для нахождения этих ошибок приходится проводить работу вручную, отделяя «настоящие» проблемы от «фальшивых».

    В итоге, робот действительно полностью брал на себя часть работы тестировщиков (например, находил все битые ссылки), но совсем не всю. И мы задумались о том, как «добавить роботу интеллекта».

    Как робот догадается об ошибке?


    Традиционно в тестировании запускают тестируемую программу с какими-то заданными входными данными и сравнивают результаты с каким-то также наперед заданным «правильным» результатом. Он может быть задан вручную, или, скажем, сохраняться при запуске предыдущей версии программы (тогда мы сможем найти все различия между данной версией и предыдущей), но общий принцип все равно остается таким. По сути подход в целом здесь не меняется десятки лет, меняются только инструменты для реализации этих тестов.
    Однако оказывается, что возможны принципиально иные подходы для определения того, что является ошибкой.

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

    Итак, где ошибка на этой странице?



    Конечно, правильный ответ — среди пяти предложений снизу есть повторяющиеся. Чтобы понять, что это ошибка, не надо быть экспертом в Маркете — надо просто обладать минимальным здравым смыслом.

    Другой пример.



    Здесь в одном месте написано «нет в продаже», а в другом — указаны цены. Опять же абсолютно любой человек понимает, что это некорректная ситуация.

    Еще один пример.



    Это просто чистая страница. То есть у нее есть стандартные «шапка» и «футер», но нет никакого контента в середине.

    Здесь и возникает ключевой вопрос — как человек понимает, что это ошибка? На каком механизме это основано?

    Мы долго думали, и кажется, что ключевое слово здесь — опыт. То есть человек уже видел в своей жизни много веб-страниц, причем некоторые были ровно такого же типа. И именно из них у него сформировался некоторый шаблон. Этот шаблон может быть как очень общим («страница не должна быть пустой», «все результаты поиска должны быть различны»), или, наоборот, привязанным к данным страницам («два выделенных блока содержат или не содержат цифры одновременно»). То есть у него в голове уже сформировались эти правила и, как мы видим по данным примерам, они выглядят совсем несложными.

    Таким образом, дальнейшая задача тут стала ясна — надо научиться автоматически извлекать эти правила, анализируя множество схожих или не очень схожих веб-страниц.

    Видно, что сформулированные правила довольно просты, и, если бы мы научились их автоматически извлекать, то можно было бы формировать автотесты без участия человека. Например, роботу дается для анализа много страниц сервисов Яндекса, и он понимает, что на них на всех снизу есть ссылка «О компании». Соответственно этот факт формулируется как правило, и робот будет проверять его выполнение для новой версии сервиса или даже для другого сервиса.

    Самое просто применение этой идеи такое: анализируем все страницы сервиса в продакшн, вычленяем такие «правила», а затем проверяем, выполняются ли они для новой версии того же сервиса.

    Этот подход давным-давно всем известен. Он называется back-to-back тестирование и есть те, кто его использует. Однако такой метод хорошо применим лишь тогда, когда работа сервиса не должна заметно меняться от версии.

    Давайте рассмотрим поисковую выдачу вчера и сегодня — результаты поиска и реклама рядом меняются. Онии зависят от региона пользователя, его предпочтений, времени суток, наконец. Соответственно, при непосредственном сравнении будет слишком много «мусора» (отметим, что в некоторых ситуациях и такой непосредственный метод допустим).

    Здесь же мы развиваем нашу идею и осуществляем сравнение, «очищенное» от мусора, — мы сравниваем не сами страницы, а некоторые «модели» страниц.

    Блоки


    Сформулировав общую идею, перейдем к тому, как же ее реализовывать. Наша задача — автоматически извлекать правила. Для понимания человеком они очень простые. Мы их формулируем на языке «блоков» — мы говорим о том, содержит определенная часть страницы какой-то элемент или нет, присутствует ли на странице определенный блок, и так далее. Для человека страница делится на них естественным образом — вот форма авторизации, вот поисковая форма (и в ней подблоки — строка поиска, кнопка «найти»). Однако робот «видит» перед собой html-код, и ему совершенно непонятно, какая часть этого кода образует блок.

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

    1. Постоянные. Весь блок целиком присутствует на каждой странице).







    2. Меняющиеся. Какой-то тэг присутствует на каждой странице, но внутри него каждый раз все меняется.







    3. Однотипные блоки на одной странице.



    4. Однотипные, но разные по сути блоки на одной странице.



    При этом на разных страницах один и тот же блок может стоять на разных местах.







    То есть для нас «блок» — это некая часть страницы, которая при её изменении остается более-менее постоянной. Например, человек легко понимает, что формы из пункта 2 (см. выше) — это частные случаи «одной и той же оранжевой формы», но при этом содержание формы меняется.

    Отдельную проблему представляют собой несколько схожих блоков, идущих подряд. Иногда это именно «несколько однотипных блоков», а иногда — набор объектов разных типов, и тогда хочется понять, какого типа объекты вообще там встречаются.

    В первую очередь нам нужен какой-то способ помечать уже выделенный блок на каждой странице. Традиционный xpath (например, /html/body/div[1]/table[2]/tbody/tr/td[2]/div[2]/ul/li[3]/span/a) плохо подходит потому, что числа в нем могут меняться — один и тот же блок может быть третьим или пятым по счету. В зависимости от того, какие еще блоки есть (см. последние два примера).

    Поэтому мы сначала убираем числа из xpath'а (получая /html/body/div/table/tbody/tr/td/div/ul/li/span/a вместо /html/body/div[1]/table[2]/tbody/tr/td[2]/div[2]/ul/li[3]/span/a) и получаем намного более стабильный вариант соответствия (то есть данный блок будет подпадать под xpath на любой странице), однако менее точный — то есть одному и тому же xpath'у теперь, конечно, может соответствовать несколько элементов. Для уменьшения этой неточности мы в описание каждого tag'а добавляем значения некоторых его атрибутов. Атрибуты мы просто руками разделили на более и менее стабильные. Например, атрибут id часто генерится заново при загрузке страницы, то есть он для нас совершенно неинформативен. Например, для блока, рассмотренного сверху, получилось такое описание: другой ipath

    <body>
    <div class="b-max-width">
    <table class="l-head">
    <tbody>
    <tr>
    <td class="l-headc">
    <div class="b-head-search" onclick="return {name:'b-head-search'}">
    <div class="b-head-searchwrap b-head-searcharrow">
    <form class="b-search">
    <table class="b-searchtable">
    <tbody>
    <tr>
    <td class="b-searchinput">
    <span class="b-form-input b-form-input_is-bem_yes b-form-input_size_16 i-bem" onclick="return {'b-form-input':{name:'b-form-input'}}">
    <span class="b-form-inputbox">
    <text src="Тип процессора Turion II">
    


    Теперь давайте искать блоки. Если представлять html-код как дерево, то наша задача — искать стабильные пути из корневой вершины (стабильность здесь означает, что путь мало меняется при изменении страницы). Алгоритм построения множества таких стабильных путей — это основная часть нашего инструмента. Строили мы его «методом проб и ошибок». То есть мы модифицировали алгоритм и смотрели на результат. Алгоритм я опишу ниже, а пока расскажу о совершенно неожиданной проблеме — мы внезапно поняли, что не знаем, как изображать, какие блоки выделились на странице.

    Действительно — блок выглядит по-разному на разных страницах. Нам хотелось получать отчет в виде чего-то, похожего на страницу, разбитую на блоки. Но какой из вариантов блока брать? Мы раз за разом натыкались на случаи, когда к нам в отчет попадал пустой или малоинформативный вариант. Нужно было как-то компактно показать все варианты на одной и той же странице. Одному из разработчиков пришла в голову удачная идея — сделать как, например, сделано на порносайтах в сервисе Coub: при наведении мышки на видео там сменяются кадры оттуда. Мы сделали ровно то же самое — если навести указатель мышки на блок, то блок этот начинает «мигать», показывая, как он выглядит на разных страницах. Это оказалось очень удобным.

    В итоге «модель страницы» выглядит примерно так (см. ниже). Можно посмотреть на нее и сразу понять, какие блоки выделились.



    Алгоритм выделения блоков


    Теперь насчет алгоритма. Базовый алгоритм выглядит следующим образом:

    1. Выбираем одну страницу из набора.
    2. Собираем с первой страницы все максимальные пути из корневой вершины в другие.
    3. Затем для каждого отобранного пути пытаемся проложить его на всех страницах.
      Если получилось проложить часть пути, отличающуюся по длине хотя бы на 4, добавляем в множество путей эту самую часть.
      Если почти получилось проложить весь путь (не дошли на 1-3 тега), то заменяем путь в наборе на этот обрубленный вариант.
    4. В результате полученные пути и соответствуют блокам. Дальше из них легко выбрать те, которые есть на всех страницах, или, скажем, на 95% страниц.

    Большим достоинством алгоритма является то, что он линейно зависит как от числа элементов первой страницы, так и от количества страниц.

    Однако как мы скоро выяснили, есть места, где алгоритм срабатывает плохо. Например, вот для этих блоков (isbn, автор и так далее):



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

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

    Генерация правил


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

    • Блок А обязательно должен присутствовать на странице.
    • Блоки А и Б должны присутствовать одновременно.
    • Блоки А и Б не могут присутствовать одновременно.

    Можно в принципе извлекать и более сложные закономерности, но мы этим пока не занимались.

    Для каких же блоков мы формируем условие первого типа? Для тех, которые встречаются на достаточно большой доле страниц. Определяется эта доля специальным параметром, который мы называем confidence level. Неправильно устанавливать этот параметр равным единице — так, как мы хотели делать изначально, по двум причинам:

    1. Одна из 100 страниц обучающей выборки может не открыться (по таймауту, например), и в результате ни одного условия об обязательном наличии блока не выделится.
    2. Среди страниц обучающей выборки случайно могут встретиться страницы с ошибками.

    Мы этот уровень значимости варьируем в зависимости от стабильности среды, на которой мы обучаем наш инструмент. Уменьшая значение параметра, можно «убирать» эффект нестабильности среды. Однако если сильно уменьшить этот параметр, то инструмент начнет выделять дополнительные неправильные закономерности. Например, если у 96% товаров есть цена, а у 4% написано «нет в продаже», то при установке параметра в 0.95 страницы с «нет в продаже» будут помечены как ошибочные. По дефолту confidence level равен 0.997.

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



    будет следующая регулярка:
    Год издания: [0-9]{4}
    Или даже такая:
    Год издания: (19|20)[0-9]{2}

    При этом сам этот блок помечен как необязательный. То есть проверяется следующее — что если такой блок есть, то в нем после слов «год издания» написано 4 цифры или даже, что написаны 4 цифры, первые две из которых 19 или 20. Примерно такой тест написал бы и человек.

    Магия на практике


    Если резюмировать, наш инструмент умеет следующее: по набору страниц мы извлекаем правила определенного типа, которые выполняются для заданного процента этих самых страниц. Как же с помощью этого искать баги? Есть два пути.

    1. Считать, что поведение, встречающееся достаточно редко, — ошибка. Это спорный тезис, однако много раз удавалось найти функциональные баги именно таким путем. Тогда достаточно проанализировать большое количество страниц на сервисе и отметить те, которые не похожи на остальные. В любом случае этот путь не подойдет, если, условно говоря, «все сломалось». Поэтому обычно мы используем другой подход.
    2. Собирать страницы из версии N сервиса (обычно просто из production), строить по ним правила. Затем брать много страниц из версии N+1 сервиса (обычно это просто testing) и проверять на них выполнение этих правил. Получается понятный список всех отличий версий N и N+1.

    Фактически во втором случае мы получаем то же самое, что и при наличии регрессионных автотестов. Однако в нашем случае есть большое, даже огромное достоинство, — код этих тестов не надо писать и поддерживать! Как только выложили новую версию сервиса, я нажимаю кнопку «перестроить все» и через несколько минут готова новая версия «автотестов».

    В качестве эксперимента по внедрению мы использовали этот подход при запуске турецкой версии Маркета. Эксперты по тестированию написали список необходимых кейсов и какие проверки делать на каких страницах. Мы краулером отобрали много страниц сервиса и разделили их на группы — страницы результатов поиска, страница категории и так далее. Дальше для каждой группы страниц автоматически построили вышеописанные правила и вручную проверили, какие из указанных проверок действительно осуществляются. Оказалось, что около 90% проверок сгенерилось автоматически. При этом ожидаемые трудозатраты на написание автотестов были около трех человеконедель, а нашим инструментом все получилось сделать и настроить за один день.

    Конечно, это не означает, что теперь любые тесты могут быть сформированы во много раз быстрее. Например, наш инструмент пока умеет автоматически создавать только статичные тесты (без динамических операций с элементами страницы).

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

    Как я и говорил, проекты Роботестер и Magic Tester — экспериментальные и делаются в исследовательском подразделении отдела тестирования. Если вы старшекурсник и вам интересно попробовать себя в наших задачах, приходите к нам на стажировку.
    Яндекс
    307,00
    Как мы делаем Яндекс
    Поделиться публикацией

    Комментарии 37

      0
      что-то market.pepelac1ft.yandex.ru не открывается

      Спасибо за статью, довольно интересно.
      А вообще, такой подход оправдан, если страницы очень разнородны и нет доступа к алгоритмам формирования страниц. У вас же есть код, который генерит страницы — пусть он сразу и модели генерит, а вы уже эти модели накладывайте на страницы. Есть конечно вероятность, что когда сломается генерация страниц, то сломается генерация моделей и тесты ничего не покажут :) Но для этого можно ведь модели брать из продакшена, а страницы из тестинга.
      мимо-проходил-диванный-теоретик
        +2
        Код у нас, конечно, есть. Но все сервисы Яндекса сделаны по-разному и получается, что мы должны в совершенно разный код вставлять модуль, который создает нам модель. А итоговый html — это нечто универсальное.
        Но, конечно, да, описанный подход тоже имеет право на жизнь.
        –10
        Если бы я был роботом, выдавал бы ошибку на всех сайтах где нет слева блока «вверх страницы».
        Постоянно, когда тыкаю слева и не попадаю вверх страницы говорю себе: «да как так можно то»?
          0
          На самом деле все зависит от того, где робот обучается :)
          Но да, это как раз пример того, что мы теперь умеем делать. Если в обучающей выборке такой блок всегда есть (даже с небольшими изменениями), то факт его наличия выделится как правило, и робот сможет сигнализировать про отсутствие такого блока.
            +1
            Еще чуть добавлю, что Вас отсутствие этого блока расстраивает именно в результате работы механизма обучения, аналогичного описанному — Вы видели такой блок на многих сайтах, Вам он показался удобным и для Вас сформировалось правило «наличие такого блока — это хорошо».
              +1
              Да, я именно это и хотел сказать :)
              Хабр приучил меня клацать в левый край страницы
              +17
              А меня наоборот такие блоки раздражают: при чтении часто выделяю текст и снимаю выделение кликом по пустому месту.
              Так что это дело вкуса.
                +4
                Ужасно разражают. Это должна быть настройка или плагин к браузеру, не более того.
                0
                В Яндекс.Браузере переход вверх страницы делается по клику на заголовок активной вкладки. :)
                  +16
                  image
                    +1
                    Ты вернулся, дарующий home! Славься ncix, славься ncix!
                  –1
                  923 кб картинка до хабраката? Пожалейте простых смертных.
                    0
                    Fixed. Извините.
                    +1
                    Не планируется ли оупен-сорс?
                      +1
                      Я теперь боюсь обещать подобное :)
                      Мы столько раз обещали, что когда-нибудь выложим Роботестера в опенсорс (и такая работа ведется!), что мне уже неудобно.
                      Короче, ответ такой: хотим! Но пока не обещаем.
                      0
                      Не очень понял, вы формируете правила по имеющемуся коду, и затем проверяете его же этими же правилами? Т.е. ситуация: вы сформировали тесты на версии N. Далее вышла версия N+1, но она, предположим, содержит много ошибок. Можете ли вы применить к ней тесты, созданные на версии N? Думаю, нет, т.к. в версии N+1 наверняка много что поменялось. Можете ли вы сформировать корректные тесты для версии N+1? Нет, т.к. она работает нестабильно.

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

                      В нашей конторе автотестировщики бьются головой о вот такую стену: функционал некоего модуля остается более-менее одним и тем же, однако с выходом новой версии внешний вид меняется довольно значительно, поэтому автотесты приходится переписывать на 100% (Поясню: у нас внешний вид стандартный на всю систему, а функционал пишется независимо от него. В новой версии может поменяться верстка страницы, вид стандартных кнопок и даже логика работы с формами ввода. При этом сам функционал может меняться незначительно.)

                      Вообще очень крутой у вас подход. Всегда хотел чем-то таким заниматься. Жаль, что я уже давно не старшекурсник.
                        0
                        Конечно, при сильном изменении верстки значительное число тестов начинают выдавать очень много ошибок. Это проблема, она существует для стандартного подхода (когда тесты пишутся вручную) и, увы, сохраняется в ситуации, когда тесты автоматически генерятся, как у нас.
                        Мы делаем некоторые вещи, чтобы уменьшить этот эффект.
                        1. Мы перестраиваем модели при каждой итерации (при каждой выкладке на тестовую среду). Тогда мы можем поймать ошибки, которые возникли ровно при этой выкладке. Ведь часто бывает так — уже вроде все проверено, почти готовы выезжать на продакшн — и надо внести «небольшое исправление». Как понять, что оно ничего не сломало? У нас уже готовы тесты в такой ситуации.
                        2. У нас есть очень много настроек, какие теги, атрибуты и части страницы не учитываются при построении модели. Все это можно настраивать. Если функциональность не изменилась, а изменились только, я не знаю, стили, то их можно просто отключить и модель, основанная на остальных данных, будет хороша.
                        Но здесь, конечно, начинается уже ручная настройка, это не так просто.

                        В целом, конечно, идеальная ситуация для применения нашего тула — когда почти ничего не изменилось и надо это проверить.
                          0
                          Этот подход про регрессионное тестирование, про то чтобы заменить или писать меньше регрессионных автотестов.
                          Когда много изменений неизбежно придется проверять иначе
                            +1
                            В свое время сделал парсер XML-файлов формата DDEX, который адаптировался к изменению схемы.
                            Проблема была в том, что при изменение версии в XML-ки может поменяться путь до определенного узла. При этом само содержимое узла почти не менялось. А если и менялось то в основном путем добавления новых подузлов.

                            Идея аналогичная, парсер знает как парсить определенные узлы и пути до этих узлов. Пути задаются в виде xpath правил. Правила, соответственно, хранятся в файле.

                            Когда парсеру поступает XML-файл для которого нет правил, парсер генерит новые правила на базе старых (анализируя пути и подбирая похожие). Так как правила сохраняются в файл, то всегда их можно подправить, если парсер немного ошибся.

                            Возможно, если предположить, что узлы — это блоки на странице, то подобное решение позволит автоматизировать процесс перехода тестирующего инструмента на другую версию верстки.
                            –15
                            Компания Яндекс то еще гнилье, сами ратуют за то что не нарушают законы однако сами же и рекламируют то что запрещено законом) c2n.me/i5sx1p.png ну о чем можно дальше разговаривать )

                            Хреного вы тестируете, мне вот интересно вас забанят наконец то или нет?
                              +6
                              Это не относится к теме статьи.
                              +1
                              Работа проделана проста огромная, читать было действительно интересно. Сори, может просто не увидела — какой процент ложных срабатываний теперь, с внедрением этой системы?
                                0
                                Мне трудно назвать число, все очень зависит от того, насколько правильно настроено все. То есть если модель построена по достаточно полной выборке, то ложных срабатываний нет, или почти нет. Однако, никогда заранее не ясно, что выборка полная. Например, когда мы только начали экспериментировать и настраивать на разных сервисах, я настраивал МТ на страницах карточек книг на Маркете. Построилась с виду хорошая модель, а потом при сверке она показала расхождение в поле ISBN для карточки одной книги. При внимательном изучении данной страницы выяснилось, что там белорусский ISBN, а во всех примерах для обучения, видимо, были русские коды. Мы добавили такой пример в обучающую выборку и все исправилось.
                                Так приходится делать часто — иногда трудно заранее понять, точно ли все случаи учтены. И при настройке ложных срабатываний может быть много. Но когда построена хорошая модель — их уже не должно быть.
                                +2
                                А цена на Note II в 195300 рублей не является ошибкой?
                                  0
                                  Интересный вопрос! У меня когда-то (когда я еще сам занимался Маркетом) была мысль, что можно так отлавливать ошибки, находя слишком большие цены. И там был какой-то телефон за 200 с чем-то тысяч. Однако, я пошел на сайт магазина и увидел, что никакой ошибки нет — это какое-то специальное исполнение телефона, под гжель, с инкрустациями и все такое :)
                                  Так что все может быть!

                                  На самом деле на Маркете есть фильтры по цене, чтобы, скажем, чехол для айфона случайно не «приклеился» к карточке айфона, но на 195300, почти уверен, они не сработают, по вышеописанной причине.
                                    0
                                    Тогда логичнее если такой «премиальный» телефон будет находиться в отдельной строчке, так же как есть разделение по цвету можно завести варианты исполнения (по аналогии с модификациями у ноутбуков).
                                    0
                                    Можно и так, например
                                      0
                                      Да, вот тут странно, что пролезло. А откуда этот скрин? Там старый интерфейс, я вижу.
                                        0
                                        Я это увидел через пару месяцев после выхода этого 4s, снял для прикола
                                    0
                                    Например, роботу дается для анализа много страниц сервисов Яндекса, и он понимает, что на них на всех снизу есть ссылка «О компании»

                                    /html/body/div/table/tbody/tr/td/div/ul/li/span/a вместо

                                    верстка однотипных блоков может быть различной на разных сервисах (<a>О компании</a>, <b>О компании</b>) — её делали разные люди, в разное время, используя разные фреймворки. или просто один и тот же блок находится в разных состояниях (ссылка на текущую страницу — не ссылка). как вы это учитываете?
                                      0
                                      Тут все зависит от того, на каких страницах обучать робота. Это решает человек. В самом простом случае роботу для обучения дается одна страница. Он открывает ее несколько раз, запоминает, что где, а что меняется при открытии, и сохраняет себе такую модель.
                                      Чуть более сложный случай — несколько схожих страниц. Например, выдача поиска по видео с разными запросами. Там разный контент, но структура страницы более-менее та же.
                                      Наконец, можно пойти дальше и дать на вход уже принципиально разные страницы одного и того же сервиса. Тогда робот извлечет как правило только наличие шапки и футера, я думаю.
                                      То есть создаются правила, которым удовлетворяет нужный процент страниц обучающей выборки. Если там везде ссылка «о компании» была сверстана одним и тем же образом — именно наличие точно такой же ссылки и будет проверяться. Если же в выборку попали разные страницы, то робот уже будет проверять наличие или блока А или блока Б, как-то так.
                                      +2
                                      Интересная у вас работа. Не так много мест, где можно разрабатывать алгоритмы, а затем видеть результат их работы (а также выгоду, которую принесли алгоритмы для бизнеса).
                                      Спасибо за статью, было интересно читать.
                                        0
                                        Спасибо за добрые слова! Да, работа очень интересная, это правда.
                                        0
                                        Условия формируются в виде регулярных выражений

                                        Правильно ли я понимаю, что регулярки, в отличие от XPath, должен написать человек? Или же есть вспомогательный алгоритм генерации регулярок?
                                          0
                                          Нет, регулярки тоже генерятся автоматически, есть специальный алгоритм. Если интересно, могу сказать, что он выдаст для каких-нибудь наборов строк.
                                            0
                                            Было бы неплохо еще одной статьей. Главным образом из-за статистики использования.

                                            Просто с тем же XPath все понятно. Само выражение имеет вполне себе заданную структуру и с ним удобно проводить предсказуемые операции. Я вот на регулярках в итоге завис. Не понятно, в каких случаях его нужно применять для анализа контента блока и построения выражений, а в каких нет. И какие атомарные единицы использовать. Пытался использовать «слова» (алфавит+цифры) и разделитель пробел, но результат получился плохой.
                                          0
                                          что ключевое слово здесь — опыт

                                          Опыт полученный через глаза. А к боту «глаза» случайно не пытались делать? Например, через PhantonJS+подлючаемый JS? Можно определить, какую часть страницы занимает блок, в какой части страницы он находится. Потому что визуально одинаковые блоки обычно находятся в примерно в одних и тех же местах, хотя по разметке от корня они могут быть совершенно не похожи.

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое