Web scraping на R, часть 2. Ускорение процесса с помощью параллельных вычислений и использование пакета Rcrawler |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2019-08-27 09:48 В прошлой статье я с помощью скрэпинга-парсинга собрал с сайтов IMDB и Кинопоиск оценки фильмов и сравнил их. Репозиторий на Github. Код неплохо справился со своей задачей, однако скрэпинг часто используют для "соскабливания" не пары-тройки страниц, а пары-тройки тысяч и для такого "большого" скрэпинга код из прошлой статьи не подходит. Точнее будет сказать не оптимален. В принципе, Вам практически ничего не мешает его использовать для задач обхода тысяч страниц. Практически, потому что столько времени у Вас просто нет Когда решил использовать scraping_imdb.R для обхода 1000 страниц Оптимизация кода. Однократное использование функции read_html В данной статье для проверки работы и скорости кода будут использоваться 100 ссылок на страницы книжного магазина "Лабиринт". Явное изменение, которое может ускорить процесс — это однократное использование самой "медленной" функции кода — Особенности скрэпинга страниц на Лабиринте В этой части я не буду касаться самой процедуры получения и очистки данных, о которых говорилось в прошлой статье. Отмечу только те моменты, с которыми при написании кода для скрэпинга книжного магазина я столкнулся впервые. Во-первых стоит сказать о структуре. Она не очень удобная. В отличии, например, от сайта Читай-города, разделы жанра при "пустых фильтрах" выдают только 17 страниц. На них, ясное дело, не умещаются все 8011 книг в жанре "Современная зарубежная проза". Поэтому я не придумал ничего лучше, чем обходить ссылки https://www.labirint.ru/books/**** простым перебором. Метод прямо скажем, не самый лучший (хотя бы потому что большинство "древних" книг никакой информации кроме названия не имеют и поэтому практически бесполезны), поэтому если кто предложит более элегантное решение, я буду рад. Зато я узнал, что под гордым первым номером на сайте Лабиринта идёт книжка "Как сделать самогон". Увы, но купить этот кладезь знаний уже невозможно. Все адреса при переборе можно разделить на два типа:
Существующие страницы, в свою очередь, можно поделить ещё на две части:
В конечном итоге я получаю таблицу данных с семью столбцами:
Со страницами с полной информацией всё понятно, никаких изменений в сравнении с кодом для киносайтов они не требуют. Что касается страниц, на которых каких-то данных нет, то с ними не всё так просто. Поиск по странице вернёт только те значения, которые найдёт и длина вывода уменьшится на то количество элементов, которые он не найдёт. Это нарушит всю структуру. Чтобы избежать этого в каждый аргумент была добавлена конструкция if...else, которая оценивает длину вектора, полученного после использования функции
Но как Вы можете заметить здесь целых два if и целых два else. К решению проблемы, описанной выше имеют отношения только "внутренние" if..esle. Наружные решают проблему с несуществующими страницами. Страницы, которых просто нет, доставляют наибольшие хлопоты. Если на на страницах с отсутствующими данными происходит смещение значений, то при подаче на вход В этом нам поможет функция
n — это список адресов страниц сайта, которые мы соскабливаем. На выходе мы получим список, длиной n, в котором элементы с существующих страниц будут в "нормальном" для выполнения функции А теперь вернёмся к коду получения названия издательства. Внешний if...else нужен для тех же целей, что и внутренний, но в отношении несуществующих страниц. Если переменная
Теперь вернёмся с ускорению процесса скрэпинга. Параллельное вычисление в R. Сравнение скорости и подводные камни при использовании функции read_html По умолчанию все вычисления в R выполняются на одном ядре процессора. И пока это несчастное ядро трудится в поте лица, "соскабливая" нам данные с тысяч страниц, остальные товарищи "прохлаждаются", выполняя какие-то другие задачи. Использование параллельного вычисления помогает привлечь к обработке/получению данных все ядра процессора, что ускоряет процесс. Я не буду глубоко вдаваться в конструкцию параллельных вычислений на R, подробнее о них Вы можете прочитать например здесь. То как я понял параллельность на R — это создания копий R в отдельных кластерах по числу указанных ядер, которые взаимодействуют друг с другом через сокеты. Сразу расскажу об ошибке, какую я совершил при использовании параллельных вычислений. Первоначально мой план был такой: Я с помощью параллельных вычислений получаю список из 100 "прочитанных"
В итоге я понял в чём проблема, посмотрев примеры в интернете, а уже после, по закону подлости, нашёл объяснение Хенрика Бенгтссона в виньетке к пакету future. Дело в том, что XML-функции пакета Само создание параллельных вычислений не занимает много времени и строк кода. Первое что нужно — загрузить библиотеки. В репозитории на Github указаны какие пакеты нужны для каких способов. Здесь я покажу параллельные вычисления с помощью функции
Далее создаём параллельно работающие копии R:
Теперь пишем функцию, которая будет делать все необходимые нам процедуры. Отмечу, что т.к. создаются новые сеансы R пакеты, функции которых используются в нашей собственной функции, следует писать в теле функции. В spider_parallel.R это приводит к тому, что пакет А дальше процедура почти ничем не отличается от использования обычной функции
Вот собственно и всё, теперь осталось сравнить затраченное время. Сравнение скорости последовательного и параллельного вычисления Это будет самый короткий пункт. Параллельное вычисление получилось в 5 раз быстрее обычного: Скорость скрэпинга без использования параллельных вычислений
Скорость скрэпинга с использованием параллельных вычислений
Что сказать? Параллельные вычисления могут сэкономить кучу Вашего времени, не создавая в создании кода каких-то сложностей. При увеличении количества ядер скорость будет расти практически пропорционально их числу. Вот так путём некоторых изменений мы ускорили код сначала в 7 раз (перестав вычислять Небольшой обзор пакета Rcrawler. Сравнение скорости. В R есть ещё несколько способов соскабливания HTML-страниц, но я остановлюсь на пакете Rcrawler. Его отличительная особенность от остальных средств в языке R — это возможность обхода сайтов. Вы можете задать одноимённой функции Для нашего случая, скрэпинга с указанных адресов, есть функция
Но при всех положительных качествах у функции Скорость скрэпинга функцией
Скорость скрэпинга функцией
Так что Rcrawler стоит использовать если Вам нужно обойти сайт без предварительного указания url-адресов, а также при небольшом числе страниц. В других случаях медленная скорость перевесит все возможные плюсы использования этого пакета. Буду благодарен за любые комментарии, пожелания, претензии Источник: habr.com Комментарии: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||