2014-08-30 2 views
0

Я пишу приложение в Ruby, которое может искать и извлекать данные с сайта с более чем 10000 страницами. Я использую OpenURI и Nokogiri открывать и анализировать веб-страницы, чтобы получить из него данные и сохранить их в локальный файл данных ::Как быстро и эффективно открывать и анализировать большое количество веб-страниц с помощью OpenURI и Nokogiri?

#An example 
page = Nokogiri::HTML(open("http://example.com/books/title001.html"))  
#Get title, author, synopsys, etc from that page 

Для меня, который имеет подключение к ADSL, она занимает в среднем 1 секунды до откройте страницу. Поскольку этот сайт имеет около 10000 страниц, для открытия всех страниц и получения данных обо всех книгах потребуется не более 3 часов, что является неприемлемым для этого приложения, потому что мои пользователи не захотят ждать много времени.

Как быстро и эффективно открывать и анализировать большое количество веб-страниц с помощью OpenURI и Nokogiri?

Если я не могу сделать это с ними, что мне делать? И как могут некоторые приложения, которые выполняют одну и ту же работу (список книг, получать все данные со страниц и сохранять в файл), например, некоторые манга-загрузчики, просто занимают 5-10 минут, чтобы сделать это с большими сайтами манги (около 10000 названий)?

ответ

1

Не используйте OpenURI первым; Существует гораздо лучший способ, если вы используете Hydra and Typhoeus.

Как современная кодовая версия мифического зверя с 100 головками змей, Typhoeus запускает HTTP-запросы параллельно, чистая инкапсуляция логики обработки.

...

Параллельные запросы:

hydra = Typhoeus::Hydra.new 
10.times.map{ hydra.queue(Typhoeus::Request.new("www.example.com", followlocation: true)) } 
hydra.run 

Дальше вниз в документации ...

Как получить массив ответов обратно после выполнения очереди:

hydra = Typhoeus::Hydra.new 
requests = 10.times.map { 
    request = Typhoeus::Request.new("www.example.com", followlocation: true) 
    hydra.queue(request) 
    request 
} 
hydra.run 
responses = request.map { |request| 
    request.response.response_body 
} 

request.response.response_body является линия, которую Вы хотите, чтобы обернуть с анализатором Nokogiri в:

Nokogiri::HTML(request.response.response_body) 

В этот момент у вас будет массив DOM для прохождения и обработки.

Но подождите! Есть больше!

Поскольку вы хотите побрить некоторое время обработки, вам нужно настроить Thread и Queue, нажать разборные DOM (или просто unparsed HTML response_body), затем обработать поток и записать файлы.

Это не сложно, но начинает ставить вопрос из области для переполнения стека, поскольку он становится маленькой книгой. Прочитайте документацию Thread и Queue, особенно раздел о производителях и потребителях, и вы должны иметь возможность собрать их вместе. Это из ri Queue документов:

= Queue < Object 

(from ruby core) 
------------------------------------------------------------------------------ 
This class provides a way to synchronize communication between threads. 

Example: 

    require 'thread' 
    queue = Queue.new 

    producer = Thread.new do 
    5.times do |i| 
     sleep rand(i) # simulate expense 
     queue << i 
     puts "#{i} produced" 
    end 
    end 

    consumer = Thread.new do 
    5.times do |i| 
     value = queue.pop 
     sleep rand(i/2) # simulate expense 
     puts "consumed #{value}" 
    end 
    end 
------------------------------------------------------------------------------ 
= Class methods: 

    new 

= Instance methods: 

    <<, clear, deq, empty?, enq, length, num_waiting, pop, push, shift, size 

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

... как могут приложения, которые выполняют одну и ту же работу (список книг, получение всех данных со страниц и сохранение в файл), например, некоторые манга-загрузчики занимают всего 5-10 минут, чтобы сделать это с большой мангой сайтов (около 10000 наименований)?

Они:

  • быстрые подключения к Интернету.
  • Мощность ЦП для обработки нескольких соединений.
  • ОЗУ для запуска нескольких потоков и хранения большого количества страниц, ожидающих обработки.

Непросто обрабатывать многие страницы, вы просто должны быть реалистами относительно своих ресурсов и использовать то, что доступно для разумного использования.

Каков мой совет?

  • Не пытайтесь открыть 100 страниц одновременно; Ваше соединение и процессор будут забиты, и вы уменьшите пропускную способность, и вы сможете голодать от своего приложения.
  • Запустите тесты, чтобы определить, где находится ваша точка убывающих возвратов, и не допускайте больше запросов одновременно, чем эта сумма.
  • Потребляющая нить легко будет оставаться впереди добывающих потоков, поэтому вам нужен только один потребитель.
0

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

Смотрите здесь: https://blog.engineyard.com/2014/ruby-thread-pool

как могут некоторые приложения, которые делают один и то же произведение (список книги, получить все данных из страниц и сохранить в файл), такие как некоторые манга загрузчики просто взять 5-10 минут, чтобы сделать это с большими сайтами манги (около 10000 названий)?

вычислительная мощность. Если у вас 10 000 основных компьютеров (или 10 000 компьютеров с одним ядром каждый), вы можете запустить один процесс для каждого запроса, а затем все запросы будут выполняться в одно и то же время. Общее время для завершения всех запросов будет всего лишь временем, затрачиваемым на самый длинный запрос, а не суммой всех запросов.

+0

Спасибо, я попробую ваше решение.Что касается вычислительной мощности, я не думаю, что это имеет место с программным обеспечением для загрузки манги, потому что даже на низкоспециализированном компьютере с высокоскоростным подключением они не занимают много времени, чтобы открывать и извлекать данные, просто занимая в основном менее 30-45 минут , Кстати, они в основном написаны на скомпилированном языке, это важно? –

+0

Я не думаю, что вычислительная мощность вашего компьютера имеет отношение к манге - это важная вычислительная мощность манги. Я не знаю, что такое манга, но если вы отправите один запрос манге, который говорит: «Получите мне все эти веб-страницы». И манга отправляет запросы, а затем агрегирует результаты и отправляет их на ваш компьютер, это вычислительная мощность манги, которая определяет, как быстро все запросы будут завершены. – 7stud

+0

:(Манга - это просто слово для японских комиксов, а не аппаратная штука. И я использую «manga downloader», потому что это программное обеспечение названо так. [Пример] (http://sourceforge.net/projects/fmd/) Извините, если вы раздражены. –