Wingardium Scrape-iosa! Scrape-io!
Table Of Content
Иногда мне нравится представлять, что у меня есть магия, чтобы мысленно или произнести некоторые слова в стиле Гарри Поттера и мои коды магическим образом становятся безошибочными, но увы:
Я студент программы по инженерии программного обеспечения в Flatiron School, и на прошлой неделе я узнал, как создавать CLI-приложение на Ruby и парсить веб-сайты с помощью Nokogiri. Звучит ли это для вас так же нелепо, как заклинания в Гарри Поттере? Не волнуйтесь, мне тоже. Давайте разберемся в некоторых из этих терминов, прежде чем мы погрузимся глубже.
Парсинг: Парсинг данных - это процесс извлечения данных с веб-сайта, чтобы вы могли использовать эти данные в программе. Например, вы можете захотеть спарсить Spotify и собрать топ-10 исполнителей на основе количества прослушиваний их песен. Для этого вы извлекаете HTML с веб-сайта и затем преобразуете его с помощью инструмента в удобочитаемую форму.
Nokogiri gem: Nokogiri gem так же волшебен, как и звучит. Это фантастическая библиотека, которая практически удовлетворяет всем нашим потребностям в парсинге HTML. Она позволяет вам преобразовывать HTML с веб-сайтов в упомянутую выше удобочитаемую форму. После установки вы, вероятно, будете использовать ее на протяжении всей своей карьеры веб-парсинга.
CLI: Интерфейс командной строки (CLI) - это место, где вы вводите команды для компьютерной программы, набирая текст, и можете видеть визуальные подсказки или ответы на вводимый текст.
Установка: Если вы хотите установить Nokogiri, используйте команду "gem install Nokogiri".
Я начал планировать свое CLI-приложение, записывая, как я представляю, что пользователь будет с ним взаимодействовать. Давайте рассмотрим проект Museum CLI gem, над которым я работал на прошлой неделе.
Процесс:
Я знал, что хочу создать проект, связанный с достопримечательностями Вашингтона, округ Колумбия, но ведь в Вашингтоне 10 000 достопримечательностей, с чего начать? Ну, это просто, я очень люблю ходить в музеи Смитсониана в Вашингтоне. Хотя я не был во всех из них, моя цель - посетить их все. Я решил спарсить https://www.si.edu/museums.
Требования:
Код:
Создание структуры файлов: Вы можете использовать "bundle gem", за которым следует название вашего гема, и это автоматически создаст структуру файлов для вас (см. Рисунок 1 и Рисунок 2 для команды и автоматически созданной структуры файлов). В качестве альтернативы вы можете создать свою собственную директорию, используя mkdir <dir_name>
, и создавать файлы с помощью touch <filename>
. Я выбрал использовать команду bundle gem и добавил нужные файлы, создав файлы scraber.rb, attraction.rb, cli.rb вручную. Полные инструкции здесь.
Добавление необходимых гемов: Я добавил все необходимые файлы в environment.rb, как показано на рисунке 3.
Добавление кода в мои классы: УБЕДИТЕСЬ, ЧТО ВЫ ТЕСТИРУЕТЕ ПО МЕРЕ НАПИСАНИЯ КОДА!
a. Класс Attraction
Поскольку я собирался парсить достопримечательности музеев Смитсониана, я решил назвать свой класс Attraction. Достопримечательность инициализируется (создается) с именем и местоположением. Я создал attr_reader (метод, который позволяет мне читать информацию в классе, но не позволяет пользователю изменять или переименовывать ее), потому что я не предполагал, что кто-то захочет изменить название или местоположение музея. Массив классов @@all будет хранить все экземпляры объектов Attraction.
Чтобы иметь возможность найти достопримечательность по ее индексу, я добавил метод @self.find_by_index в класс Attraction. Это позволило мне искать по индексу экземпляры достопримечательностей, хранящиеся в массиве @@all. Используя классовый метод (.find_by_index) на рисунке 5 ниже, я указываю, что я хочу начать с 1 (зная, что элементы массива начинаются с индекса 0) и отображать каждую достопримечательность с индексом.
b. Класс Scraper
Примечание для начинающих: некоторые веб-сайты сложнее парсить, чем другие. Выберите веб-сайт с хорошей структурой для обучения, и вы сможете перейти к более сложному парсингу после достаточной практики. Например, IMDB очень хорошо подходит для начинающих, которые только учатся парсить сайт, потому что на одной странице размещено много разной информации. Веб-сайт Смитсониана более сложный, потому что он перечисляет дополнительную информацию на отдельных страницах (например, на их сайте может быть написано "нажмите здесь, чтобы узнать больше" и перенаправить вас на другую страницу, чтобы поделиться информацией о выставках или часах работы).
Если веб-страница размещена на удаленном сайте, например, https://www.si.edu/museums, то вам следует включить модуль open-URI, который является частью стандартного распределения Ruby, но должен быть явно подключен (я подключил его в файле env). Open-URI выполняет всю работу по выполнению HTTP-запроса в методе open, делая операцию такой же простой, как открытие файла на собственном жестком диске.
Откройте URL веб-сайта, который вы выбрали для парсинга, щелкните правой кнопкой мыши и выберите "Inspect". Выберите определенный элемент, который вы хотите исследовать, и посмотрите, какой класс охватывает информацию, которую вы хотите спарсить. В моем проекте осмотр показал мне, что первый элемент - это строка поиска [0], которую я удалил с помощью метода .shift, и что заголовок достопримечательности находится в классе title. Однако я понял, что класс с заголовком достопримечательности дает мне только заголовок, чтобы пройти на уровень ниже, мне нужно было найти класс, который охватывает и заголовок, и местоположение. Для моего второго уровня парсинга я снова проинспектировал веб-сайт (мне потребовалось некоторое время, чтобы разобраться!), и это показало мне, что информация, которую мне нужно спарсить, находится во втором элементе [1] в массиве классов .inner. Второй элемент содержал дополнительную информацию о каждом экземпляре достопримечательности. Я решил спарсить местоположение каждой достопримечательности. Чтобы получить к нему доступ, я извлек его в текстовом формате и использовал методы .gsub и .strip, чтобы удалить ненужные символы и лишние пробелы.
c. Класс CLI
Здесь происходит магия командной строки. В моем методе экземпляра #run я вызвал метод класса Scraper Sraper.scrape_attractions, чтобы получить доступ к спарсенным данным для имени и местоположения. Затем я вызвал методы класса CLI welcome, list attractions и menu, вызвав .self на них. Обратите внимание, что .self в этом методе подразумевается, вы можете решить явно добавить его или оставить его.
Метод экземпляра #menu содержит логику, содержащую цикл, который прерывается, когда пользователь вводит "exit". Он предлагает пользователю выбрать номер, чтобы отобразить местоположение, вызывая метод #user_selection. Основываясь на вводе пользователя, я вызывал метод Attraction.find_by_index из класса достопримечательности и присваивал его переменной attraction. Затем я создал проверку, чтобы убедиться, что ввод пользователя - это число от 0 до 24 и что ввод пользователя - это допустимые символы или "exit", и если ввод пользователя не соответствует допустимому вводу, вызывается метод #error_message.
Как это работает!!
В соответствии с требованиями, которые я собрал:
Советы и полученные уроки
Вот несколько советов для всех перед их первым проектом по парсингу в Flatiron (или где бы вас ни привел код).
Ты сможешь это!