Modern technology gives us many things.

[Перевод] Мой первый прототип поискового движка

139

Уровень сложности Средний Время на прочтение 6 мин Количество просмотров 2K Блог компании RUVDS.com Поисковые технологии *Программирование *Анализ и проектирование систем *SQLite * Туториал Перевод Автор оригинала: R. S. Doiel

[Перевод] Мой первый прототип поискового движка

Я реализовал первый прототип собственного механизма поиска, который сокращённо назвал PSE (Personal Search Engine). Создал я его с помощью трёх скриптов Bash, возложив всю основную работу на sqlite3, wget и PageFind.

Браузер Firefox вместе с Newsboat сохраняют полезную информацию в базах данных SQLite. В moz_places.sqlite содержатся все посещённые URL-адреса и адреса закладок (то есть moz_bookmarks.sqlite базы данных SQLite). У меня получилось около 2000 закладок. Это меньше, чем я предполагал, так как многие оказались нерабочими из-за битых ссылок.

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

Кэш Newsboat cache.db обеспечил богатый источник контента и намного меньше мёртвых ссылок (что не удивительно, поскольку я мониторю этот список URL-адресов гораздо активнее, нежели закладки). Из обоих этих источников я собрал 16,000 страниц. Затем с помощью SQLite 3 я запросил из разных БД значения URL, упорядочив их в одном текстовом файле построчно.

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

После сбора содержимого я использовал PageFind для его индексирования. Поскольку я стал использовать PageFind изначально, то сопроводил этот инструмент опцией —serve, которая предоставляет веб-службу localhost на порту 1414. Всё, что мне требовалось – это добавить файл index.html в каталог, где я собрал всё содержимое и сохранил индексы PageFind. После этого я снова использовал PageFind для предоставления собственного механизма поиска на базе localhost.

Читать на TechLife:  Предновогодние мини-ПК: 5 отличных девайсов на разные случаи жизни

И хотя общее число страниц было невелико (16,000), мне удалось получить интересные результаты, просто опробуя случайные слова. Так что прототип получился перспективный.

▍ Текущие компоненты прототипа

Я использую простой скрипт Bash, который получает URL-адреса из закладок Firefox и кэша Newsboat, после чего генерирует файл pages.txt с уникальными URL.

Далее, используя этот файл, с помощью wget я собираю и организую всё содержимое в структуру дерева:

  • htdocs
    • http (все URL-адреса с типом соединения HTTP);
    • https (все URL-адреса с типом соединения HTTPS);
    • pagefind (здесь содержатся индексы PageFind и JavaScript-код интерфейса поиска);
    • index.html (здесь находится страница для интерфейса поиска, использующего библиотеки из pagefind).

Поскольку я скачал только HTML, 16K страниц заняли на диске не сильно много места.

▍ Реализация прототипа

Вот скрипты Bash для получения URL-адресов, сбора контента и запуска локального движка поиска на основе PageFind.

После сбора URL-адресов я использую две переменные среды для обнаружения различных баз данных SQLite 3 (то есть PSE_MOZ_PLACES и PSE_NEWSBOAT):

1. #!/bin/bash 2. 3. if [ «$PSE_MOZ_PLACES» = «» ]; then 4. printf «the PSE_MOZ_PLACES environment variable is not set.» 5. exit 1 6. fi 7. if [ «$PSE_NEWSBOAT» = «» ]; then 8. printf «the PSE_NEWSBOAT environment variable is not set.» 9. exit 1 10. fi 11. 12. sqlite3 «$PSE_MOZ_PLACES» 13. ‘SELECT moz_places.url AS url FROM moz_bookmarks JOIN moz_places ON moz_bookmarks.fk = moz_places.id WHERE moz_bookmarks.type = 1 AND moz_bookmarks.fk IS NOT NULL’ 14. >moz_places.txt 15. sqlite3 «$PSE_NEWSBOAT» ‘SELECT url FROM rss_item’ >newsboat.txt 16. cat moz_places.txt newsboat.txt | 17. grep -E ‘^(http|https):’ | 18. grep -v ‘://127.0.’ | 19. grep -v ‘://192.’ | 20. grep -v ‘view-source:’ | 21. sort -u >pages.txt
Следующим шагом я с помощью wget получаю страницы:

1. #!/bin/bash 2. # 3. if [ ! -f «pages.txt» ]; then 4. echo «missing pages.txt, skipping harvest» 5. exit 1 6. fi 7. echo «Output is logged to pages.log» 8. wget —input-file pages.txt 9. —timestamping 10. —append-output pages.log 11. —directory-prefix htdocs 12. —max-redirect=5 13. —force-directories 14. —protocol-directories 15. —convert-links 16. —no-cache —no-cookies
Наконец, у меня есть скрипт, который генерирует страницу index.html и XML-файл в формате OpenSearch Description, индексирует собранные сайты и запускает PageFind в режиме сервера:

Похожие сообщения

1. #!/bin/bash 2. mkdir -p htdocs 3. 4. cat <<OPENSEARCH_XML >htdocs/pse.osdx 5. <OpenSearchDescription xmlns=»http://a9.com/-/spec/opensearch/1.1/» 6. xmlns:moz=»http://www.mozilla.org/2006/browser/search/»> 7. <ShortName>PSE</ShortName> 8. <Description>A Personal Search Engine implemented via wget and PageFind</Description> 9. <InputEncoding>UTF-8</InputEncoding> 10. <Url rel=»self» type=»text/html» method=»get» template=»http://localhost:1414/index.html?q={searchTerms}» /> 11. <moz:SearchForm>http://localhost:1414/index.html</moz:SearchForm> 12. </OpenSearchDescription> 13. OPENSEARCH_XML 14. 15. cat <<HTML >htdocs/index.html 16. <html> 17. <head> 18. <link 19. rel=»search» 20. type=»application/opensearchdescription+xml» 21. title=»A Personal Search Engine» 22. href=»http://localhost:1414/pse.osdx» /> 23. <link href=»/pagefind/pagefind-ui.css» rel=»stylesheet»> 24. </head> 25. <body> 26. <h1>A personal search engine</h1> 27. <div id=»search»></div> 28. <script src=»/pagefind/pagefind-ui.js» type=»text/javascript»></script> 29. <script> 30. window.addEventListener(‘DOMContentLoaded’, function(event) { 31. let page_url = new URL(window.location.href), 32. query_string = page_url.searchParams.get(‘q’), 33. pse = new PagefindUI({ element: «#search» }); 34. if (query_string !== null) { 35. pse.triggerSearch(query_string); 36. } 37. }); 38. </script> 39. </body> 40. </html> 41. HTML 42. 43. pagefind 44. —source htdocs 45. —serve
Затем я просто указываю в браузере адрес http://localhost:1414/index.html. При желании я могу даже передать строку запроса ?q=….

С функциональной точки зрения это очень примитивная система, и 16К страниц явно недостаточно для того, чтобы сделать её привлекательной для использования (думаю, для этого нужно где-то 100К).

▍ Чему я научился на этом прототипе

Текущий прототип имеет несколько ограничений:

  1. Мёртвые ссылки в файле pages.txt значительно замедляют процесс сбора содержимого. Мне нужно найти способ исключить попадание таких ссылок в этот файл или наладить их удаление из него.
  2. В выводе PageFind используются страницы, скачанные мной на локальную машину. Было бы лучше, если бы получаемые ссылки переводились и указывали на фактический источник страницы. Думаю, это можно реализовать с помощью JS-кода в файле index.html при настройке элемента PageFind, отвечающего за результат поиска. Этот вопрос нужно изучить подробнее.

16K страниц – это очень скромный объём. В ходе тестирования я получил интересные результаты, но недостаточно хорошие для того, чтобы начинать реально использовать эту систему поиска. Предполагаю, что для более-менее полноценного её применения нужно собрать хотя бы 100К страниц.

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

Читать на TechLife:  В Японии прекратили продавать Toyota Land Cruiser 300 и Alphard

На данный момент значительное время занимает сбор содержимого страниц в индекс. Я пока не знаю, сколько конкретно места потребуется для планируемого объёма в 100К страниц.

Настройка индексирования и интерфейса поиска оказалась простейшим этапом процесса. С PageFind гораздо легче работать, нежели с корпоративными приложениями для поиска.

▍ Предстоящие доработки

Я вижу несколько способов расширения поискового массива. Первый подразумевает создание зеркал для нескольких сайтов, которые я использую в качестве ссылок. В wget есть функция зеркала. Опираясь на список из sites.txt, я мог бы периодически отображать эти сайты, делая их содержимое доступным для индексирования.

Экспериментируя с опцией зеркала, я заметил, что получаю PDF-файлы, привязанные к отображаемым страницам. Если я использую команду Linux find для обнаружения всех этих PDF, то смогу применить другой инструмент для извлечения их текста. Таким образом я расширю свой поиск за пределы простого текста и HTML. Нужно хорошенько продумать этот вариант, так как в конечном итоге я хочу иметь возможность восстанавливать путь к PDF при отображении этих результатов.

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

Для просмотра интересных страниц из моего RSS-агрегатора я использую приложение Pocket. У этого приложения есть API, и я могу получать из него дополнительные интересные страницы. В Pocket также есть различные организованные списки, в которых может присутствовать интересное содержимое для сбора и индексирования. Думаю, нужно будет реализовать механизм сопоставления выдаваемых системой предложений с определённым списком исключений. Например, нет смысла пытаться собрать содержимое платёжного шлюза или коммерческих сайтов в целом.

Помоги спутнику бороться с космическим мусором в нашей новой игре! 🛸

[Перевод] Мой первый прототип поискового движка

Теги:

  • ruvds_перевод
  • поисковый движок
  • sqlite
  • wget
  • pagefind

Хабы:

  • Блог компании RUVDS.com
  • Поисковые технологии
  • Программирование
  • Анализ и проектирование систем
  • SQLite

Источник

Оставьте ответ

Ваш электронный адрес не будет опубликован.

©Купоно-Мания.ру