Давайте разработаем приложение для парсинга веб-страниц в реальном времени с R — намного проще, чем с Python
Трудно найти хороший набор данных. Это ожидаемо, но бояться нечего. Такие методы, как очистка веб-страниц, позволяют нам получать данные из любого места в любое время — если вы знаете, как это сделать. Сегодня мы узнаем, насколько просто очистить веб-данные с помощью R и сделать это с помощью красивого графического интерфейса R Shiny.
Итак, что такое парсинг веб-страниц? В двух словах, это всего лишь метод сбора данных с различных веб-сайтов. Его можно использовать, когда:
- Нет доступного набора данных для необходимого анализа.
- Общедоступного API нет
Тем не менее, вы всегда должны проверять политику сайта в отношении парсинга веб-страниц вместе со статьей Этика парсинга веб-сайтов. После этого вы сможете, руководствуясь здравым смыслом, решить, стоит ли чистка.
Если что-то не так, не делайте этого.
К счастью, некоторые веб-сайты созданы исключительно для отработки веб-скрейпинга. Один из них — books.toscrape.com, на котором, как следует из названия, перечислены составленные книги разных жанров:
Итак, давайте теперь поскребем этого ублюдка, ладно?
План атаки
Откройте веб-страницу, щелкните любые две категории (боковая панель слева) и проверьте URL-адрес. Вот наш выбор:
https://books.toscrape.com/catalogue/category/books/travel_2/index.html https://books.toscrape.com/catalogue/category/books/mystery_3/index.html
Что общего у этих URL-адресов? Все, кроме выделенной жирным шрифтом части. Это сама категория. Понятия не имею, в чем дело с нумерацией, но так оно и есть. Каждая страница содержит список книг, а отдельная книга выглядит так:
Наша задача — собрать информацию по каждой книге в категории. Для этого требуется немного знаний HTML, но это простой язык разметки, поэтому я не вижу здесь проблемы.
Мы хотим очистить:
- Заголовок — свойство h3 ›a› title.
- Рейтинг — атрибут p.star-rating ›class.
- Цена — div.product_price ›div.price_color› text.
- Доступность — div.product_price ›div.instock› text
- URL книги — div.image_container ›a› href свойство
- URL эскиза — свойство div.image_container ›img› src
Теперь вы все знаете, так что давайте начнем со скребка.
Выскабливание книг
Пакет rvest
используется в R для выполнения задач очистки веб-страниц. Он очень похож на dplyr
, известный пакет анализа данных, из-за использования оператора конвейера и поведения в целом. Мы знаем, как добраться до определенных элементов, но как реализовать эту логику в R?
Вот пример того, как очистить названия книг в категории путешествия:
library(rvest) url <- 'https://books.toscrape.com/catalogue/category/books/travel_2/index.html' titles <- read_html(url) %>% html_nodes('h3') %>% html_nodes('a') %>% html_text()
Разве не все было просто? Аналогичным образом мы можем очистить все остальное. Вот сценарий:
library(rvest) library(stringr) titles <- read_html(url) %>% html_nodes('h3') %>% html_nodes('a') %>% html_text() urls <- read_html(url) %>% html_nodes('.image_container') %>% html_nodes('a') %>% html_attr('href') %>% str_replace_all('../../../', '/') imgs <- read_html(url) %>% html_nodes('.image_container') %>% html_nodes('img') %>% html_attr('src') %>% str_replace_all('../../../../', '/') ratings <- read_html(url) %>% html_nodes('p.star-rating') %>% html_attr('class') %>% str_replace_all('star-rating ', '') prices <- read_html(url) %>% html_nodes('.product_price') %>% html_nodes('.price_color') %>% html_text() availability <- read_html(url) %>% html_nodes('.product_price') %>% html_nodes('.instock') %>% html_text() %>% str_trim()
Потрясающие! В качестве последнего шага давайте склеим все это в один фрейм данных:
scraped <- data.frame( Title = titles, URL = urls, SourceImage = imgs, Rating = ratings, Price = prices, Availability = availability )
На этом вы можете закончить статью и завершить ее, но мы можем построить еще кое-что из этого — простое и легкое в использовании веб-приложение. Давай сделаем это дальше.
Веб-приложение для парсинга
В R есть фантастическая библиотека для разработки веб-приложений и информационных панелей — Shiny
. Его гораздо проще использовать, чем что-либо подобное в Python, поэтому мы будем его придерживаться. Для начала создайте новый R-файл и вставьте внутрь следующий код:
library(shiny) library(rvest) library(stringr) library(glue) ui <- fluidPage() server <- function(input, output) {} shinyApp(ui=ui, server=server)
Это шаблон, который требуется каждому приложению Shiny. Затем давайте настроим пользовательский интерфейс. Нам понадобятся:
- Заголовок — просто большой жирный текст поверх всего (необязательно)
- Боковая панель — содержит раскрывающееся меню для выбора жанра книги.
- Центральная область — отображает вывод таблицы после очистки данных.
Вот код:
ui <- fluidPage( column(12, tags$h2('Real-time web scraper with R')), sidebarPanel( width=3, selectInput( inputId='genreSelect', label='Genre', choices=c('Business', 'Classics', 'Fiction', 'Horror', 'Music'), selected='Business', ) ), mainPanel( width=9, tableOutput('table') ) )
Далее нам нужно настроить функцию сервера. Он должен переназначить наши красиво отформатированные входные данные на часть URL (например, «Business» на «business_35») и очистить данные для выбранного жанра. Мы уже знаем, как это сделать. Вот код для функции сервера:
server <- function(input, output) { output$table <- renderTable({ mappings <- c('Business' = 'business_35', 'Classics' = 'classics_6', 'Fiction' = 'fiction_10', 'Horror' = 'horror_31', 'Music' = 'music_14') url <- glue('https://books.toscrape.com/catalogue/category/books/', mappings[input$genreSelect], '/index.html') titles <- read_html(url) %>% html_nodes('h3') %>% html_nodes('a') %>% html_text() urls <- read_html(url) %>% html_nodes('.image_container') %>% html_nodes('a') %>% html_attr('href') %>% str_replace_all('../../../', '/') imgs <- read_html(url) %>% html_nodes('.image_container') %>% html_nodes('img') %>% html_attr('src') %>% str_replace_all('../../../../', '/') ratings <- read_html(url) %>% html_nodes('p.star-rating') %>% html_attr('class') %>% str_replace_all('star-rating ', '') prices <- read_html(url) %>% html_nodes('.product_price') %>% html_nodes('.price_color') %>% html_text() availability <- read_html(url) %>% html_nodes('.product_price') %>% html_nodes('.instock') %>% html_text() %>% str_trim() data.frame( Title = titles, URL = urls, SourceImage = imgs, Rating = ratings, Price = prices, Availability = availability ) }) }
Вот и все — теперь мы можем запустить приложение и проверить его поведение!
Именно то, что мы хотели — просто, но все же вполне понятно. Давайте подведем итоги в следующем разделе.
Напутственные слова
Всего за пару минут мы перешли с нуля на рабочее приложение для парсинга веб-страниц. Варианты масштабирования безграничны — добавляйте больше категорий, работайте над визуальными элементами, включайте больше данных, лучше форматируйте данные, добавляйте фильтры и т. Д.
Надеюсь, вам удалось уследить за мной и вы смогли оценить всю мощь веб-скрапинга. Это был фиктивный веб-сайт и фиктивный пример, но подход остается неизменным, не имеющим отношения к источнику данных.
Спасибо за прочтение.
Первоначально опубликовано на https://www.betterdatascience.com 19 октября 2020 г.