- PHP 62.5%
- HTML 36.1%
- PowerShell 0.8%
- JavaScript 0.6%
| browser | ||
| data | ||
| downloads | ||
| tools | ||
| README.md | ||
Парсер и помощник для Moodle-тестов
Этот проект помогает сохранять правильные ответы из тестов Moodle и затем показывать их повторно.
Сейчас в проекте есть два режима работы:
-
moodle_quiz_helper.user.js
Основной и самый удобный вариант. Это userscript для Tampermonkey, который работает прямо в браузере на сайте теста. -
quiz_tools.ps1
Офлайн-инструмент для разбора уже сохраненных HTML-страниц теста.
Структура проекта
tests_parser/
├─ browser/
│ └─ moodle_quiz_helper.user.js
├─ data/
│ └─ answers_db.json
├─ downloads/
│ ├─ page_7.htm
│ └─ page_7_files/
├─ tools/
│ └─ quiz_tools.ps1
└─ README.md
Главный сценарий использования сейчас такой:
- открыть вопрос в браузере
- ответить и отправить его на проверку
- дождаться, пока сервер вернет страницу с результатом
- userscript увидит правильные ответы и сохранит их локально
- при следующем появлении того же вопроса скрипт подсветит известные правильные варианты
Что умеет проект
Проект умеет:
- определять тип вопроса на странице
- извлекать правильные ответы из уже проверенной страницы
- сохранять локальную базу известных ответов
- сопоставлять новые вопросы с уже известными
- подсвечивать правильные ответы прямо на странице теста
Сейчас поддерживаются типы вопросов:
multichoiceВ том числе:- несколько правильных вариантов через
checkbox - один правильный вариант через
radio
- несколько правильных вариантов через
gapselect
Структура проекта
Основные файлы
-
moodle_quiz_helper.user.js
Userscript для Tampermonkey. Работает прямо в браузере на странице Moodle. -
quiz_tools.ps1
PowerShell-скрипт для офлайн-разбора сохраненных HTML-файлов. -
answers_db.json
Локальная база знаний для офлайн-режима. Появляется после запускаquiz_tools.ps1. -
downloads/
Папка для сохраненных HTML-страниц и связанных с ними ресурсов вродеpage_7_files.
Примечание по структуре
Офлайн-дампы теперь лучше складывать в папку downloads/.
Так корень проекта остается чистым:
- код лежит отдельно
- база лежит отдельно
- сохраненные страницы не мешают навигации по репозиторию
Быстрый старт: браузерный режим
Это основной рекомендуемый способ.
Что нужно
- Firefox или другой браузер
- установленный Tampermonkey
Установка
- Открой Tampermonkey.
- Создай новый userscript.
- Удали шаблонный код.
- Вставь содержимое файла moodle_quiz_helper.user.js.
- Сохрани скрипт.
- Убедись, что он включен.
Как проверить, что все работает
- Открой страницу вопроса на сайте Moodle.
- Если вопрос уже был проверен сервером, скрипт:
- прочитает правильные ответы со страницы
- сохранит их
- покажет зеленый блок с известными ответами
- подсветит правильные варианты
- Если вопрос еще не проверен, но этот же вопрос уже встречался раньше:
- скрипт найдет его в локальной базе
- сразу покажет известные правильные ответы
Как выглядит работа скрипта
На странице появляется:
- зеленый информационный блок с известными ответами
- в баннере ответы показываются вместе с буквами вариантов, например
b. ... - зеленая подсветка правильных вариантов
- маленькая метка
из базырядом с правильным вариантом - если ответ еще не известен, сверху показывается красный баннер с сообщением об этом
Для вопросов типа gapselect:
- рядом с полем выбора появляется аккуратная подсказка
- рядом показывается правильный вариант
- само поле выбора скрипт не изменяет, чтобы не ломать отображение браузерного списка
Где хранятся ответы в браузере
Userscript хранит данные в localStorage браузера.
Ключ хранения:
quiz_answer_db_v1
Это значит:
- база хранится локально в твоем браузере
- она не отправляется на сервер этим скриптом
- при очистке данных сайта или
localStorageбаза может пропасть
Посмотреть содержимое можно через консоль браузера:
JSON.parse(localStorage.getItem("quiz_answer_db_v1"))
Технический принцип работы userscript
1. Скрипт запускается на странице теста
В moodle_quiz_helper.user.js задано правило:
@match https://hochuuchitsa.schoolattestation.ru/mod/quiz/*
Значит скрипт активируется на страницах тестов Moodle этого сайта.
2. Скрипт ищет блоки вопросов
Он находит элементы:
.que
Это корневые контейнеры вопросов Moodle.
3. Определяется тип вопроса
Сейчас поддерживаются:
multichoiceЭто общий тип Moodle для двух сценариев:- выбор одного ответа
- выбор нескольких ответов
gapselect
Тип определяется по CSS-классам корневого блока вопроса.
4. Определяется состояние вопроса
Скрипт проверяет классы:
correctincorrectpartiallycorrectnotyetanswered
Это позволяет понять:
- вопрос уже проверен сервером
- вопрос еще не проверен
5. Извлекается текст вопроса
Скрипт берет содержимое:
.qtext
После этого:
- удаляет служебные скрытые элементы
- нормализует пробелы
- заменяет
selectна маркер[blank], чтобы сигнатура вопроса была стабильной
6. Извлекаются правильные ответы
Для multichoice
Скрипт:
- собирает варианты ответов из:
checkbox, если можно выбрать несколько вариантовradio, если можно выбрать только один вариант
- смотрит блок
.rightanswer, если он есть - если текста правильного ответа нет или он неудобен, дополнительно ориентируется на класс
correctу варианта
Для gapselect
Скрипт:
- находит все
select - читает блок
.rightanswer - извлекает правильные слова из текста вида:
[правильный ответ]
7. Вопрос сохраняется в локальную базу
Скрипт использует два способа идентификации вопроса:
-
qidиз скрытых данных Moodle
Это основной и самый надежный идентификатор. -
сигнатура вопроса
Еслиqidпо какой-то причине недоступен, строится хеш от:- типа вопроса
- текста вопроса
- текста вариантов ответа
8. При повторном открытии вопроса скрипт ищет его в базе
Если вопрос найден:
- добавляет баннер с известными правильными ответами
- подсвечивает правильные варианты
9. Скрипт следит за изменениями DOM
Используется MutationObserver, чтобы страница обрабатывалась:
- после загрузки
- после частичных обновлений интерфейса
При этом в скрипте уже есть защита от зацикливания на собственных изменениях DOM.
Как устроена логика сопоставления вопросов
Сопоставление работает так:
- Если у вопроса есть
qid, используется ключ:
qid:12345
- Если
qidнет, используется сигнатура:
sig:...
Это нужно для того, чтобы:
- не терять известные ответы
- корректно находить тот же вопрос в будущем
- переживать мелкие изменения страницы
Офлайн-режим через PowerShell
Этот режим полезен, если у тебя есть уже сохраненные HTML-файлы и хочется разобрать их локально.
Показать, что распарсилось из файла
powershell -ExecutionPolicy Bypass -File .\tools\quiz_tools.ps1 show .\downloads\page_7.htm
Обучить базу по одному файлу
powershell -ExecutionPolicy Bypass -File .\tools\quiz_tools.ps1 learn .\downloads\page_7.htm
Обучить базу по всем *.htm в папке downloads
powershell -ExecutionPolicy Bypass -File .\tools\quiz_tools.ps1 learn-all
Создать локальную аннотированную копию HTML
powershell -ExecutionPolicy Bypass -File .\tools\quiz_tools.ps1 annotate .\downloads\page_7.htm
После этого появится:
- answers_db.json
- файл вида
page_7.annotated.htm
Важно:
- офлайн-режим ожидает, что сохраненные HTML-файлы лежат в
downloads/ - команда
learn-allпо умолчанию читает именно эту папку - при необходимости можно передать другой путь через параметр
-DownloadsPath
Когда ответ сохраняется, а когда нет
Ответ сохраняется только если страница уже содержит результат проверки от сервера.
То есть вопрос должен быть в одном из состояний:
correctincorrectpartiallycorrect
Если вопрос в состоянии:
notyetanswered
то ответ еще не считается известным и в базу не сохраняется.
Известные ограничения
Сейчас проект:
- не поддерживает все возможные типы вопросов Moodle
- рассчитан в первую очередь на ту структуру Moodle, которую мы уже увидели на этом сайте
- уже поддерживает
multichoiceв обоих вариантах: одиночный выбор и множественный выбор - хранит браузерную базу в
localStorage, а не в отдельном внешнем файле - не делает экспорт и импорт базы ответов
Что можно улучшить дальше
Возможные следующие шаги:
- добавить экспорт и импорт базы ответов в JSON
- сделать кнопку очистки базы
- добавить панель статистики: сколько вопросов уже известно
- расширить поддержку других типов вопросов Moodle
- добавить более удобную визуализацию правильных ответов
Кратко
Если коротко, проект работает так:
- Ты открываешь тест в браузере.
- Сервер возвращает страницу с результатом ответа.
- Userscript извлекает правильные ответы.
- Сохраняет их локально.
- При следующем появлении того же вопроса показывает уже известный правильный ответ.
Именно это и есть основная цель проекта.