Превосходство в мелочах со штаб-квартирой с помощью системы пользовательского поиска Google (СПП)

В последнее время я вижу много сообщений о людях, которые успешно нашли способ обмануть популярную мобильную игру «HQ Trivia». Они сразу же вызвали у меня интерес. Как человек, которому нравится находить более эффективные способы выполнения задач, я решил, что хочу попробовать свои силы в создании собственного бота-викторины. Кроме того, прежде чем я углублюсь в детали, НЕ используйте подобные методы в живых играх; это одновременно противоречит условиям использования штаб-квартиры, не говоря уже о полной аморальности. Разобравшись с этим, давайте узнаем, как создать одного из этих ботов.

Часть 1: Распознавание вопроса и ответов

Поскольку у меня есть и MacBook, и iPhone, я могу использовать проигрыватель Quicktime для зеркалирования экрана телефона и компьютера. Это позволяет делать снимки экрана и вычисления в реальном времени. Традиционно самой сложной частью всего этого уравнения было бы на самом деле разбор конкретных вопросов и ответов из данного снимка экрана, но, к счастью, это упрощается благодаря проектам оптического распознавания символов (OCR) с открытым исходным кодом. В частности, я имею в виду Tesseract, который предоставляет очень чистый интерфейс командной строки для анализа текста из изображений. Из Python после импорта библиотеки подпроцесса я могу использовать строку:

subprocess.Popen ([‘/ usr / bin / tesseract’, ‘./sc.png’, ‘output’, ‘-l’, ‘eng’]). wait ()

для вывода воспринимаемого текстового содержимого изображения в файл с именем «output.txt» (при условии, что снимок экрана называется «sc.png»). Предполагая, что на фотографии нет ничего, кроме вопросов и ответов, достаточно просто создать указатель, который добавляет каждую букву к переменной вопроса, пока не встретит вопросительный знак. После этого он сохраняет местоположение, и каждая новая строка представляет собой данный ответ. Если это не имело большого смысла, вот [немного неэффективный] код, который я использовал для выполнения задачи:

И вуаля, это даст вопросы и ответы (в данном случае называемые опциями), сохраненные как отдельные переменные. А теперь самое интересное.

Часть 2: Анализ лучшего ответа

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

Метод 1. Ответ "Control-F"

Безусловно, наиболее очевидный подход - просто ввести вопрос в Google и нажать Ctrl-F для всех случаев данного ответа. Звучит просто, правда? Ну вроде как. Очень быстро после попытки использовать этот метод я столкнулся с некоторыми проблемами. Первое из них заключалось в том, что Google фактически не возвращает результаты поиска при поиске из инструмента командной строки unix «curl», что было не так уж важно. Я только что перешел на Google CSE и использовал их REST API для поиска меня. Другая проблема заключалась в том, что если в вопросе был термин «нет», наименее распространенный ответ был на самом деле правильным. Однако ни одна из этих проблем не может быть решена с помощью всего лишь нескольких строк дополнительного кода. Нет, настоящая проблема была на самом деле в самой методологии. Если вы ищете на веб-странице термин, состоящий не более чем из одного слова (а это большинство ответов HQ), то очень маловероятно, что вы найдете что-либо, кроме точных символьных совпадений. Это представляет собой проблему, заключающуюся в том, что, если веб-сайт использует только первое из двух или трех слов в данном ответе, моя программа не распознает его. Чтобы исправить это, я решил просто искать на странице только самое подходящее слово, как определено моей программой.

Предполагая, что возможные ответы передаются в виде массива «a», лучше всего использовать либо второе слово, если слов более двух, либо последнее слово, если слов меньше двух. Как видите, после этого выполняется проверка, чтобы убедиться, что слово, которое я ищу, не используется ни в одном другом ответе или вопросе. Это предотвращает сценарий, в котором ответы будут «Вьетнамская война», «Первая мировая война» и «Вторая мировая война», и моя программа будет искать слово «война» в результатах каждого ответа. Наконец, если слово оканчивается на «s», я отбрасываю его, потому что даже если слово не во множественном числе, оно не будет иметь большого значения при поиске термина («трава» в значительной степени то же самое, что «gras ”При использовании Ctrl-F). После этого было легко найти все совпадения из возвращенной полезной нагрузки JSON, просто разделив на основе выбранного слова и добавив единицу к длине этого массива.

Метод 2: подсчет результатов поиска

Проблема с предыдущим методом заключается в том, что когда он работает, он чрезвычайно точно дает правильный ответ, однако существует множество сценариев, которые дают 0 для всех трех ответов. В этом случае полезно иметь другой, хотя и менее точный, метод перекрестной ссылки. Это огромное количество результатов поиска Google. Вы когда-нибудь видели что-то подобное?

Дело в том, что, хотя меня могут и не волновать все результаты 50700, меня волнует само число. Позволь мне объяснить. Если я введу в Google вопрос, за которым следует один термин, например: «Что из перечисленного является частью парусной лодки? AND Jib », и сделайте это для каждого ответа, правильный ответ обычно дает больше всего результатов поиска. Кроме того, я помещаю слово И между вопросом и ответом, чтобы активировать логические операторы поиска Google, которые в основном предписывают Google искать только те страницы, которые относятся к вопросу И ответу. Собрав данные о результатах для каждого возможного ответа, я могу использовать их для сравнения с результатами метода 1, который обычно дает пугающе точные результаты. Вопросы, с которыми он борется, - это такие, как «В каком из следующих штатов самый высокий почтовый индекс?» которые требуют сложного сравнения, которое легко для нас, но трудно для точного отображения данных Google. Тем не менее, по моим подсчетам, мой бот обычно делает все правильно примерно в 75–85% случаев. Пример игры можно найти ниже, когда я запускал ее, может быть, на моем третьем записанном сеансе, и в ней было правильно задано 10/12 вопросов.

Если вам интересно узнать больше о том, как я это сделал, или вы просто хотите взглянуть на исходный код, его можно найти на моем Github вместе со многими другими интересными проектами.