Ruby Mechanize, Nokogiri и Net::HTTP

Я использую Net::HTTP для HTTP-запросов и получаю ответ:

uri = URI("http://www.example.com")
http = Net::HTTP.start(uri.host, uri.port, proxy_host, proxy_port)
request = Net::HTTP::Get.new uri.request_uri
response = http.request request # Net::HTTPResponse object
body = response.body

Если мне нужно использовать гем Nokogiri для анализа этого HTML-ответа, я сделаю:

nokogiri_obj = Nokogiri::HTML(body)

Но если я хочу использовать гем Mechanize, мне нужно сделать следующее:

agent = Mechanize.new
mechanize_obj = agent.get("http://www.example.com")

Могу ли я использовать Net::Http для получения ответа HTML, а затем использовать гем Mechanize для преобразования его в объект Mechanize вместо использования agent.get()?


РЕДАКТИРОВАТЬ:

Причина обхода метода agent.get() заключается в том, что я пытаюсь использовать EventMachine::Iterator для выполнения одновременных запросов EM-HTTP.

EventMachine.run do
  EM::Iterator.new(urls, 3).each do |url,iter|
    puts "giving   #{url}   to httprequest now"
    http = EM::HttpRequest.new(url).get
    http.callback { |resp|
      uri = resp.send(:URI, url)
      puts "inside callback of #{url}"
      body = resp.response
      page = agent.parse(uri, resp, body)
    }
    iter.next
  end
end

Но это не работает. Я получаю сообщение об ошибке:

/usr/local/rvm/gems/ruby-1.9.3-p194/gems/mechanize-2.5.1/lib/mechanize.rb:1165:in`parse': undefined method `[]' for #<EventMachine::HttpClient:0x0000001c18eb30> (NoMethodError)

когда я использую метод parse для Net::HTTP, он отлично работает, и я получаю объект Mechanize:

 uri = URI("http://www.example.com")
 http = Net::HTTP.start(uri.host, uri.port, proxy_host, proxy_port)
 request = Net::HTTP::Get.new uri.request_uri
 response = http.request request # Net::HTTPResponse object
 body = response.body
 agent = Mechanize.new
 page = agent.parse(uri, response, body)     

Я передаю неправильные аргументы для метода parse при использовании em-http?


person HPC_wizard    schedule 21.08.2012    source источник
comment
Почему вы хотите это сделать? Agent.get намного проще.   -  person pguardiario    schedule 21.08.2012
comment
Вы делаете слишком много работы. Mechanize позаботится об get за вас. Mechanize также использует Nokogiri для внутреннего синтаксического анализа, поэтому можно запросить проанализированный документ Nokogiri для выполнения дополнительных поисков.   -  person the Tin Man    schedule 21.08.2012
comment
Я отредактировал вопрос .. спасибо   -  person HPC_wizard    schedule 21.08.2012


Ответы (2)


Я не уверен, почему вы думаете, что использование Net::HTTP было бы лучше. Mechanize будет обрабатывать перенаправления и файлы cookie, а также предоставляет готовый доступ к проанализированному документу Nokogiri.

require 'mechanize'

agent = Mechanize.new
page = agent.get('http://www.example.com')

# Use Nokogiri to find the content of the <h1> tag...
puts page.at('h1').content # => "Example Domains"

Обратите внимание, что установка user_agent не требуется для доступа к example.com.


Если вы хотите использовать многопоточный движок для извлечения страниц, взгляните на Typhoeous и Hydra.

person the Tin Man    schedule 21.08.2012
comment
да ... на самом деле я использую Mechanize таким же образом позже в коде, чтобы очистить необходимые данные. Но мне было интересно, могу ли я объединить em-http с механизацией, как указано в вопросе. - person HPC_wizard; 22.08.2012
comment
Я бы рекомендовал использовать Typhoeus. Смотрите мой дополнительный комментарий в моем ответе. - person the Tin Man; 22.08.2012

Похоже, что у Mechanize есть метод parse, так что это может работать:

mechanize_obj = Mechanize.parse(uri, response, body)
person Casper    schedule 21.08.2012
comment
спасибо @Casper..Mechanize.parse метод работает правильно для Net::HTTP...как я могу использовать то же самое для em-http? Я думаю, что передаю неправильные аргументы методу 'parse' при использовании его с em-http.. - person HPC_wizard; 22.08.2012
comment
@Gameboy Я бы опубликовал новый вопрос по этой проблеме. Я не уверен, что класс ответа em-http совместим с ответом Net::HTTP, которого ожидает Mechanize. Возможно, вам придется что-то исправить или преобразовать ответ, чтобы он был совместимым. - person Casper; 22.08.2012