Nano Hash - криптовалюты, майнинг, программирование

Создание веб-краулера на Ruby. Как решить проблемы с производительностью?

Я создаю веб-сканер на Ruby, Rails в качестве внешнего интерфейса. Я использую Mechanize, который построен поверх Nokogiri. Я уже реализовал решение, которое будет сканировать веб-страницы, но я хочу иметь возможность сканировать 200 000 веб-сайтов за один раз, и я знаю, что есть лучший способ, чем ждать его завершения часами. Я хочу иметь возможность добиться наилучшей производительности, запуская параллельные запросы, не делая их слишком сложными. Я ничего не знаю о многопоточности и ее ограничениях, поэтому не держите сервер в заложниках, пока работает сканер, если кто-то захочет указать, где я могу узнать, как это сделать, или, по крайней мере, сказать мне, что я должен делать. находясь в поиске. Имейте в виду, что я буду писать в базу данных и в файл (вероятно, я смогу экспортировать из базы данных после завершения обхода и не писать в файл напрямую). Спасибо.

Примечание. Здесь, в SO, есть аналогичный вопрос, но ему несколько лет, возможно, люди делают это по-другому сейчас и кажутся очень сложными.


Ответы:


1

Посмотрите на использование Typhoeus и Hydra. Они упростят параллельную обработку URL-адресов.

Вам не нужно использовать Mechanize, если только вам не нужно запрашивать специальные данные с каждой страницы. Для обычного поискового робота вы можете получить тело и проанализировать его с помощью Open::URI и Nokogiri без накладных расходов Mechanize или дополнительных функций. Для ваших целей замените Open::URI на Typhoeus и позвольте Hydra управлять потоками.

Помните, что сканирование 200 000 веб-сайтов перегрузит вашу пропускную способность, если вы попытаетесь выполнить их все сразу. Это сделает ваш сайт Rails недоступным, поэтому вам нужно ограничить свои запросы. А это значит, что вам придется делать их в течение нескольких (или многих) часов. Здесь скорость не так важна, как поддержание вашего сайта в сети. Я бы, вероятно, разместил сканер на отдельной машине от сервера Rails и позволил базе данных связать все вместе.

Создайте таблицу или файл, содержащий URL-адреса сайтов, которые вы сканируете. Я бы порекомендовал таблицу, чтобы вы могли составить форму для редактирования/управления URL-адресами. Вы захотите отслеживать такие вещи, как:

  • Время последнего сканирования URL. (дата/время)
  • Нужно ли сканировать определенный URL-адрес (логический или char1)
  • URL-адрес (строка или var char[1024] должны подойти). Это должен быть уникальный ключ.
  • Просматривается ли этот URL в настоящее время (логическое значение или char1). Это очищается в начале прогона для всех записей, затем устанавливается и сбрасывается, когда паук загружает эту страницу.
  • Поле, показывающее, в какие дни можно запускать этот сайт.
  • Поле, показывающее, в какие часы можно запускать этот сайт.

Последние два важны. Вы не хотите сканировать небольшой сайт с недостаточной мощностью и прерывать его соединение. Это отличный способ получить бан.

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

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

Когда вы столкнетесь с новыми URL-адресами, проверьте, не являются ли они исходящими URL-адресами, что заставит вас покинуть этот сайт, если вы перейдете по ним. Если это так, не добавляйте их в свою таблицу URL.

Запись информации базы данных в файлы, вероятно, не поможет, потому что для поиска нужного файла вам, вероятно, все равно придется выполнять поиск в базе данных. Просто сохраните то, что вам нужно, в поле и запросите его напрямую. 200 тысяч строк для базы данных — это ничто.

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

24.09.2012

2

Я не эксперт по Ruby, но вот некоторые идеи, основанные на опыте работы с другими языками программирования, и ответы:

А. вы должны понимать модель многопоточности вашего веб-сервера или среды, в которой работает Ruby. применение.
Например, я использую веб-сервер под названием tomcat, чтобы можно было настроить количество открываемых им потоков.
Конечно, это не может превышать количество возможных потоков в вашей ОС.

B. Кроме того, имейте в виду, что, поскольку вам нужно «сканировать», это означает, что вам, вероятно, нужно работать с файлами (например, файловыми дескрипторами в Linux), а они ограничены в ресурсах.
Например, в Linux вы можете настроить лимит файловых дескрипторов с помощью ulimit.

C. Я настоятельно рекомендую вам иметь пул потоков (я уверен, что в Ruby для этого есть фреймворки, здесь это то, что я придумал, когда гуглил).
Использование пула потоков означает, что вы используете потоки, но не открываете и не закрываете потоки, а вместо этого имеете группу потоков, извлекающих задания из общей структуры данных и выполняющих их.
Например, вы можете выполнить для каждого задания следующий псевдокод:
1. Разобрать веб-страницу
2. Для каждой ссылки выполнить:
2.1. Создать задание с URL.
2.2 Поместите задание в очередь (для работы потоков пула)

Я бы также серьезно рассмотрел возможность использования кластеризации (например, несколько машин в облаке) и разработки масштабируемого решения.
Это означает, что у вас будет какая-то общая структура данных (возможно, база данных или база данных NoSQL) между узлами кластера, и что ваши рабочие потоки будут извлекать задания и размещать новые задания в этом кластере (в облаке). общая структура данных.
Я также рекомендую вам прочитать о шаблоне map-reduce, который может вам помочь здесь,
и, возможно, использовать Hadoop с Ruby (см. здесь ссылка).


Еще раз извините, я не эксперт по рубину, но я столкнулся с вашей проблемой на других компьютерных языках, которые я использую.
Надеюсь, я дал вам несколько советов и материалов для чтения. Удачи!

22.09.2012

3

Проверьте http://anemone.rubyforge.org/index.html.

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

22.09.2012
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

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

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..