Αυτοματοποίηση Εργασιών Πλοήγησης με το Mechanize [για ruby]
Posted by superuser
Μετά από την παρουσίαση του hpricot και τους τρόπους ξεψαχνίσματος των σελίδων (x)html θα περάσουμε στο επόμενο στάδιο, δλδ θα αρχίσουμε να ελέγχουμε και να μηχανοποιούμε τις εργασίες πλοήγησης χρησιμοποιώντας το Mechanize (έχει καταγωγή από Python) και εκεί θα δούμε πολύ ενδιαφέροντα πράγματα.
Αν πρέπει να ορίσω το Mechanize θα έλεγα πως είναι ένας αυτόματος υπολογιστικός πλοηγητής κειμένου για τη γλώσσα προγραμματισμού ruby. Με το mechanize θα καταφέρουμε να αυτοματοποιήσουμε τις εργασίες πλοήγησης, αφού θα μπορούμε να καλούμε ιστοσελίδες, να βρίσκουμε και να επιλέγουμε συνδέσμους, να εισάγουμε στοιχεία σε φόρμες και να τις αποστέλλουμε. Αν και το mechanize προβάλλει μόνο τα δυναμικά στοιχεία της σελίδας (links, forms, buttons, ...) τα καλά νέα είναι πως συνεργάζεται - για την ακρίβεια εξαρτάται από το hpricot, οπότε για τις στατικές πληροφορίες (κείμενο, εικόνες, ...) θα καλούμε το hpricot. Πολλά έγραψα ας περάσω στα πειράματα μου:
ΕγκατάστασηΩς συνήθως μέσω gems:
$ gem install mechanize --include-dependencies
Εξαρτήσεις και μέσο
Για κάθε παράδειγμα που ακολουθεί θα πρέπει να δηλώνονται:
require 'rubugems' # πιθανώς για windows Λ.Σ. να μην χρειάζεται
require 'mechanize'
agent = WWW::Mechanize.new
# agent.set_proxy("proxy.server.my", "8080") # MONON αν τρέχετε πίσω από proxy
Ο agent είναι στην ουσία το μέσο πλοήγησης. Αν πρέπει να κλικάρω σε ένα σύνδεσμο ή να πατήσω ένα κουμπί θα καλέσω τον agent. Είναι αντικείμενο κλάσης WWW::Mechanize.
Πρώτο Τεστpage = agent.get("http://www.google.gr/")Η page (WWW::Mechanize::Page) αποτελείται από μια σειρά συστατικών που πιθανώς να θέλουμε να εξετάσουμε {url}{meta}{title}{iframes}{frames}{links}{forms}. Από αυτά τα πιο σημαντικά είναι οι σύνδεσμοι (links) που μας επιτρέπουν την πλοήγηση και οι φόρμες που μας επιτρέπουν να εισάγουμε στοιχεία. Για να έχετε μια γενική εικόνα μελετήστε τα περιεχόμενα της σελίδας με
pp page
ΣΥΝΔΕΣΜΟΙ (LINKS)
Το σύνολο των links που περιέχονται στη σελίδα είναι κλάσης WWW::Mechanize::List,
ενώ κάθε σύνδεσμος είναι τύπου WWW::Mechanize::Page::Link.
puts page.links # WWW::Mechanize::Page::List
Δεν είναι πολύ χρήσιμη αυτή η μορφή. Αν θέλουμε όλο το κείμενο των links ή όλες τις διευθ.url των links, πολύ απλά θα θα πρέπει να εφαρμόσουμε τη μέθοδο each στη λίστα.
# ___'Ολα τα ονόματα συνδέσμων__
page.links.each { |link| puts link.text } # _____Όλες οι διευθύνσεις _________ page.links.each { |link| puts link.href }
Συνδυάζοντας τις δύο παραπάνω μπορούμε να αναπαράγουμε τα links σε κώδικα html Για την ορθότητα του αποτελέσματος θα υποθέσουμε πως όλοι οι σύνδεσμοι είναι σε απόλυτη διαδρομή δλδ ξεκινούν με http://www.google.gr/
page.links.each do |link| puts "<a href=\"" + link.href + "\">" + link.text + "</a>" end
Αν υπάρχει συνδυασμός σχετικών και απόλυτων διαδρομών συνδέσμων - όπως στην περίπτωση της σελίδας google.gr, μπορείτε να λύσετε εύκολα το πρόβλημα. Για παράδειγμα, στη συνέχεια κάνω ένα έλεγχο αν το link ξεκινάει από http (οπότε είναι απόλυτη η διαδρομή), αν όχι προσθέτω το υπολλειπόμενο συστατικό δλδ το http://www.google.gr.
BASE = "http://www.google.gr"
page.links.each do |link|
if link.href =~ /^http/ then
puts "<a href=\"" + link.href + "\">" + link.text + "</a>"
else
puts "<a href=\"" + BASH + link.href + "\">" + link.text + "</a>"
end
endΚαθόλου άσχημα! Κατάφερα να συμμαζέψω όλα τα links και τα έχω έτοιμα προς χρήση.
Τι γίνεται αν θέλω κάποιο συγκεκριμένο link;
Εύρεση Συνδέσμων
Βρείτε κάποιο σύνδεσμο δίνοντας pp page.links. Για παράδειγμα:
#<WWW::Mechanize::Page::Link #"Gmail" #"http://mail.google.com/mail/?hl=el&tab=wm">
Παρατηρήστε πως μπορώ να διακρίνω ένα σύνδεσμο από το κείμενο του ("Gmail") ή από το url του ("http://mail.google.com/mail/?hl=el&tab=wm"). Αν αναζητώ ένα link γνωρίζοντας ακριβώς το κείμενο του συνδέσμου ή το url
page.links.text('Gmail')
page.links.href('http://mail.google.com/mail/?hl=el&tab=wm')Φυσικά τις περισσότερες φορές θα χρησιμοποιήσουμε μόνο κάποιο συστατικό του κειμένου ή του url για να βρούμε το σύνδεσμο που ψάχνουμε. Σε αυτή την περίπτωση χρησιμοποιούμε RegExp = regular expressions. Η ιδέα δεν αλλάζει, αλλά μπορεί να έχω παραπάνω από ένα σύνδεσμο ως αποτέλεσμα αναζήτησης.
page.links.text(/mail/) # βρίσκει τα links που περιέχουν τη λέξη mail page.links.href(/mail/) # βρίσκει links με url που περιέχει mail
Και τώρα ήρθε η ώρα να κλικάρουμε ένα link. Θυμάστε τον agent; Λοιπόν η μορφή είναι agent.click [link] όπου [link] χρησιμοποιήστε τους άνωθεν τρόπους αναζήτησης
page_gmail = agent.click page.links.text("Gmail")Διαπιστώστε πως μεταφερθήκατε στη σελίδα του Gmail με pp page_gmail Από κει και πέρα μπορείτε να πλοηγηθείτε ατελείωτα και να αυτοματοποιήσετε τις αναζητήσεις σας. Να ψάξετε για νέα links και να συμπληρώσετε φόρμες. Αυτό θα παρουσιάσω στο δεύτερο μέρος του Mechanize.
Εύρεση, Συμπλήρωση και Αποστολή Μιας Φόρμας
Ας υποθέσουμε πως θέλουμε να βρούμε από το youtube.com βίντεο με θέμα "athens olympic games". Η κοινή πρακτική είναι να πάμε με τον browser στο youtube.com και στην πρώτη φόρμα που θα βρούμε να δηλώσουμε στο πεδίο αναζήτησης "athens olympic games". Ακριβώς την ίδια διαδικασία θα ακολουθήσω και με το mechanize.
require 'rubygems'
require 'mechanize'
agent = WWW::Mechanize.new
page = agent.get("http://www.youtube.com/")
Μέχρι εδώ όλα μας είναι γνωστά από την προηγούμενη παρουσίαση. Δώστε pp page και εστιάστε στη φόρμα:
#<WWW::Mechanize::Form
{name "searchForm"}
{method "GET"}
{action "/results"}
{fields
#<WWW::Mechanize::Form::Field:0x348ea88 @name="search_query", @value="">
#<WWW::Mechanize::Form::Field:0x348de58 @name="search_type", @value="">}
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons}>
Αυτή είναι η πρώτη φόρμα αναζήτησης στην αρχική σελίδα του youtube.com . Για να την επιλέξω (παρατηρήστε πως υπάρχουν και άλλες) θα πρέπει να δηλώσω ή το όνομα της - δλδ. searchForm - ή τον controller(action) που θα επεξεργαστεί τη φόρμα μετά την αποστολή - δλδ /results. Πολλές φορές θα βρείτε φόρμες όπου δεν εμφανίζεται το όνομα τους, οπότε και θα πρέπει να δηλώνετε αναγκαστικά τον controller.
vres_form = page.form_with( :action => '/results' )
Στη φόρμα υπάρχουν δύο πεδία, to ένα με όνομα/@name "search query" και το άλλο με "search_type". Και τα δύο πεδία είναι κενά (@value = ""). Ας θέσουμε λοιπόν στο πεδίο search_query την τιμή "athens olympic games"
vres_form.search_query = "athens olympic games"
Δείτε πως ανανεώθηκε η τιμή της μεταβλητής @value του πεδίου search_query:
pp vres_form
#<WWW::Mechanize::Form
{name "searchForm"}
{method "GET"}
{action "/results"}
{fields
#<WWW::Mechanize::Form::Field:0x343e498 @name="search_query",
@value="athens olympic games">
#<WWW::Mechanize::Form::Field:0x343dca0 @name="search_type", @value="">}
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons}>
Το μόνο που μας απομένει είναι να "πατήσουμε" το κουμπί αποστολής/submit. Πολύ απλά
myvideo_links = vres_form.click_button
Η νέα σελίδα (myvideo_links) περιέχει τα links των βίντεο σχετικά με τους ολυμπιακούς αγώνες της Αθήνας. Όπως και στο πρώτο μέρος μπορούμε να αποσπάσουμε τις ονομασίες των links και των url διευθύνσεων ή ότι άλλο επιθυμείτε να βρείτε. Για παράδειγμα :
myvideo_links.links.href(/watch\?v=/).each do |lnk|
puts lnk.text
end
Opening Ceremony Olympic Games 2004 Athens
2004 Olympic 800m Final
Fani Halkia wins 400mH in Athens Olympic Games 2004
Taekwondo Athens Olympic games 2004 -58 Men Chinese Tiapei vs Mexico Round 1
The Emblem of the 2004 Athens Olympic Games
2004 Olympic Judo Highlights 1/2
Olympic games in Athens - Syrtaki dancing - Lifetime moment ........





