Интерактивный парсер web страниц

Всем привет. Меня зовут Влад и по профессии я Java Backend.

Для начала вкратце введу в курс дела. 3 года назад ко мне в голову закралась навязчивая мысль написать интерактивный словарь-помощник для чтения на английском языке. И с тех пор начались мои приключения в мире расширений для браузеров на ядре Chrome’а.

80849ba63312f9532b7cce52b1fd08ee.png

Идея была такова. Вот у нас есть страница. Что если её всю спарить и отрисовать каждое слово на ней как интерактивный элемент. Кликаешь на него и слово летит в Wordbook (Аля личный словарь). Это слово сразу на всей странице окрашивается в какой-то цвет, в зависимости от уровня.

Для простоты пусть это будут цвета — [Красны / Оранжевый / Жёлтый / Зелёный]. Синим отмечались сами интерактивные слова, не добавленные в словарь.

322d0c8d1153c68eda4b005bec37a4ee.png

Ты можешь по этому слову кликать. Открывается меню и ты можешь поменять уровень знания слова.

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

В контексте английского раньше часто пользовался. Основную проблему я таким образом решил (Маленький словарный запас, стал приемлемым). Отмечу что читал на английском я и до этого много, а плагин лишь стал костылём на турбо тяге.

Если хотите попробовать. Можете вбить в расширениях Reckue-Languages, если хотите. Найдёте без проблем.

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

Появился новый блок? Спарсим, не пропустим.

Single Page Application? Без проблем и её перерисуем.

И работает довольно шустро, на перерисовку Документации ES6 у плагина уходит 3 секунды (на моём железе).

Но проблем тоже масса. Плагин жрёт много ресурсов. И не все машинки с этим справляются.

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

А про то что ссылки постоянно прячутся среди интерактивных блоков, которые тоже по факту ссылки…

Несовместимость модульного и стандартного js кода, привела меня к использованию webpack.

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

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

Reckue/reckue-langs: It’s your vocabulary-book built-in any pages you visit. (github.com)

Следующая статья будет про решение, которое я пишу прямо сейчас, с кодом и пояснениями. При клике на слово, вычистятся его позиция внутри блока. На вход мы принимаем event, а на выходе выдаём слово.

        const parser = new Parser(event);
        const word = parser.getWord();

Там вычисляется масса параметров, чтобы найти сначала блок внутри текста, потом посчитать index символа, на котором у нас курсор и распарсить само слово.

5672091a82e3c22f4dab9d4a7124b83b.png

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

Справедливости ради гуглил я не долго.

Вот одна из статей из которой я в начале подтырил код: Определение размеров текста / Хабр (habr.com)

© Habrahabr.ru