Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 15 di 32
  • livello principiante
Indice lezioni

WWW::Mechanize

Una libreria che consente di creare veri e propri user-agent
Una libreria che consente di creare veri e propri user-agent
Link copiato negli appunti

Concludiamo questo capitolo illustrando l'utilizzo di Mechanize, una potente libreria per l'automatizzazione delle operazioni sul Web. Mechanize gestisce automaticamente i cookie, i form, i redirect, i link e tutto quello che è possibile trovare in una pagina web.

Vediamo subito un esempio che ci permette di illustrare come è possibile operare su una pagina web:

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new

page = agent.get('http://ruby-it.org/') 

La pagina non ci viene fornita sotto forma di HTML ma come un oggetto di tipo WWW::Mechanize::Page che è la forma sotto la quale Mechanize incapsula il codice HTML. Ogni elemento della pagina è rappresentato come un oggetto o un attributo della classe WWW::Mechanize.

Per ottenere il codice HTML va utilizzato il metodo get_file al posto di get.

Particolare enfasi è riservata ai form e ai link rappresentati rispettivamente da oggetti di tipo WWW::Mechanize::Form e WWW::Mechanize::Page::Link. Come esempio per illustrare la gestione dei form vediamo come effettuare il login ad un blog su WordPress utilizzando Mechanize.

Innanzitutto creiamo un oggetto WWW::Mechanize che ci permetta di interagire con la pagina web:

agent = WWW::Mechanize.new
wp = agent.get('https://wordpress.com/wp-login.php') 

Per poter fare il login ci occorre conoscere i nomi dei campi del form. Li possiamo dal codice sorgente della pagina o direttamente da Mechanize:

wp_form = wp.forms.first
puts "#{wp_form.name} (#{wp_form.method})"

wp_form.fields.each do |f| 
  puts "  " + f.name + ":  " + f.value if f.value
end

Nel nostro esempio il form è uno ma in casi più complessi è possibile iterare sui vari form attraverso il metodo forms della pagina:

wp.forms.each do |form|
  puts form.name
end

Tornando all'esempio, wp_form è un oggetto WWW::Mechanize::Form costituito a sua volta dai vari elementi del form ovvero i campi (Field), i bottoni (Button, RadioButton), liste (SelectList), etc. Ogni campo f del form è invece di tipo WWW::Mechanize::Form::Field con gli attributi name e value. Nel nostro caso l'output sarà simile a questo:

loginform (POST)
  log:
  pwd:
  redirect_to:  wp-admin/
  testcookie:  1

Per chiarezza ipotizziamo di conoscere sia il nome del form sia quello dei campi. Quindi per fare il login e ottenere la pagina di amministrazione del nostro blog basta solo compilare il form e inviare i dati attraverso il metodo submit che simula la pressione del tasto indicato come secondo argomento:

wp_form = wp.form('loginform')

wp_form.log = 'username'
wp_form.pwd = 'password'

res = agent.submit(wp_form, wp_form.buttons.first)

Ovviamente il risultato sarà un oggetto di tipo WWW::Mechanize::Page. Nel nostro caso il tasto da premere è wp_form.buttons.first, ovvero:

>> pp wp_form.buttons.first
#<WWW::Mechanize::Form::Button:0xb76a5880 @name="wp-submit", @value="Log In">

In caso di form più complessi possiamo iterare sui bottoni attraverso l'attributo buttons come abbiamo fatto per i campi del form. La gestione degli altri elementi del form è altrettanto efficace. Ad esempio nel nostro form c'è il classico checkbox "Remember me" che può essere selezionato semplicemente:

cb = wp_form.checkboxes.first

cb è di tipo WWW::Mechanize::Form::CheckBox, per selezionarlo va utilizzato il metodo check. Il seguente stralcio di sessione Irb illustra gli attributi e il metodo check dei CheckBox:

>> pp cb
#<WWW::Mechanize::Form::CheckBox:0xb76a6078
 @checked=false,
 @name="rememberme",
 @value="forever">
=> nil
>> cb.check
=> true
>> pp cb
#<WWW::Mechanize::Form::CheckBox:0xb76a6078
 @checked=true,
 @name="rememberme",
 @value="forever">
=> nil

Come già detto Mechanize gestisce automaticamente i cookie, è possibile vedere i cookie salvati attraverso il metodo cookies.

agent.cookies.each do |c|
  puts c.to_s
end

Ogni cookie è un oggetto di classe WWW::Mechanize::Cookie che oltre al nome e al valore (mostrati da to_s) ha altri utili attributi come domain, expires, discarded, max_age, secure, etc.

Vediamo infine come Mechanize permette di gestire i link. Iniziamo come al solito creando un agente e recuperando la pagina desiderata con get:

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new
rubini = agent.get('http://rubini.us') 

Per ottenere semplicemente l'elenco dei link presenti nella pagina occorre utilizzare il metodo links che ci restituisce una lista (WWW::Mechanize::List) di oggetti WWW::Mechanize::Page::Link:

puts "Links on #{rubini.title}"
rubini.links.each do |link|
  puts "#{link.text} (#{link.href})"
end

e in output avremo una lista del genere:

Links on Rubinius : The Ruby Virtual Machine
  Home (/)
  Download (/download)
  Documentation (/rbx_documentation)
  Contribute (/contribute)
  Community (/community)
  FAQ (/faq)
  News (/news)
  Ruby (http://ruby-lang.org)
  RSpec (http://rspec.rubyforge.org)
  Rubinius on Lighthouse (http://rubinius.lighthouseapp.com/)
  Evan Phoenix (http://blog.fallingsnow.net)
  the BSD license (http://en.wikipedia.org/wiki/BSD_license#Terms)

Di notevole utilità è il metodo click che permette di aprire un link semplicemente indicandone il nome, ad esempio se dalla pagina vista di prima vogliamo aprire la pagina delle FAQ basta solo clickare sul link giusto:

faq_page = agent.click rubini.links.text('FAQ')

Ti consigliamo anche