Важное примечание: соблюдайте авторские права и этические принципы — это руководство предназначено исключительно для образовательных целей!

Введение

Я живу во Вьетнаме, где английский не является нашим родным языком. Недавно я разработал приложение с использованием Rust и Tauri-rs (подробнее об этом можно прочитать здесь).

Основные функции приложения связаны с хранением 3000 наиболее часто используемых английских слов вместе с их соответствующими вьетнамскими переводами. Кроме того, приложение отправляет периодические уведомления каждые 30 секунд, чтобы ввести новое слово, что позволяет пользователям учиться пассивно. Этот подход сродни встрече с рекламными объявлениями на улице, которые остаются с вами, даже если вы не ищете их активно.

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

Библиотеки

Tl-rs

Согласно моим исследованиям в Google, tl-rs высоко ценится как надежная библиотека для разбора HTML. они также доказывают это сами, предоставляя бенчмарк на своем сайте.

Реквест

Этот HttpClient очень популярен в сообществе Rust благодаря удобному API, отличной документации и надежной поддержке асинхронности.

Создание проекта

Для начала давайте в общих чертах рассмотрим структуру проекта и основной рабочий процесс.

Это также время жизни нашего HTTP-запроса.

Создать проект

cargo new --bin crawler

Добавьте зависимости

Обратите внимание, что reqwest использует tokio-rs как зависимость. Поэтому, чтобы выполнить асинхронный код из основного метода, нам нужно включить tokio в качестве зависимости в наш проект. Anyhow служит удобным унифицированным механизмом обработки ошибок для типов Result в нашем проекте. Мы не хотим явно сопоставлять все ошибки из зависимостей с ошибками, характерными для нашего приложения. Вместо этого мы можем сосредоточиться на обработке бизнес-логики, не отвлекаясь на тонкости распространения ошибок.

Код

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

Основной метод

Во-первых, наша цель — создать HTTP-клиент, который можно будет повторно использовать для всех запросов. Проект reqwest предлагает удобный и хорошо документированный пример кода для демонстрационных целей. Однако важно отметить, что они рекомендуют создавать и сохранять HTTP-клиент, чтобы использовать преимущества пула соединений.

Вот веб-сайт, который мы собираемся сканировать

Мы изменим наш код в основном методе, выполним запрос на получение и распечатаем необработанный HTML.

Результат огромен, но нам нужна только небольшая его часть.

Вот где Tl-rs действительно превосходит других. Благодаря надежным встроенным функциям запросов, он предлагает беспрепятственный анализ и фильтрацию тегов в HTML-документе, предоставляя эргономичные функции для эффективного извлечения данных.

Например, если мы хотим извлечь произношение слова «access» как «[‘ækses]», мы можем добиться этого, выполнив запрос для извлечения элемента div, содержащего классы «p5l fl cB».

Мы внесли изменения в основную функцию и ввели две дополнительные функции.

В основной функции мы используем функцию get_dom для создания объекта VDom из необработанного HTML-кода, полученного с помощью reqwest. . Затем мы делегируем задачи разбора и извлечения внутреннего текста внутри div функции extract_pronunciation.

Функция get_dom — это простая и понятная реализация. Он принимает необработанный HTML-код в качестве входных данных и возвращает соответствующий объект VDom. Важно отметить, что время жизни VDom связано со временем жизни нашей строки HTML, поскольку функция tl::parse принимает ссылку на строку, а не потреблять его.

Функция extract_pronunciation немного сложнее. Он получает объект VDom и значение query_selector, пытаясь получить внутренний текст целевого элемента div. Если запрос не находит совпадений, возвращается значение Нет. Процесс начинается с выполнения запроса, и если он дает результат, мы перебираем каждый узел и извлекаем внутренний текст с помощью функции inner_text().

После внесения изменений в наш код выполнение приведенного выше фрагмента кода приведет к выводу Some(“[‘ækses]”)на консоли.

С этого момента мы выполнили все необходимые задачи для извлечения данных из HTML-документа и интеграции их в наш домен.

Заключение

Обработка и извлечение HTML могут быть сложными и приятными в работе. Tl-rs и Reqwest проделали отличную работу по абстрагированию от сложностей и предоставлению нам удобного API. Добавленная поддержка асинхронных операций является ценным бонусом, улучшающим общее впечатление.

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