SlideShare uma empresa Scribd logo
1 de 52
Baixar para ler offline
Universidad de Oviedo   Programa de extensión universitaria




     CLOUD COMPUTING.
DESARROLLO DE APLICACIONES Y
        MINERÍA WEB


                               Miguel Fernández Fernández
                                miguelff@innova.uniovi.es
Screen scraping
Porqué screen scraping
  La Web es fundamentalmente para
         humanos (HTML)
Porqué screen scraping
  La Web es fundamentalmente para
         humanos (HTML)
Porqué screen scraping
                  La Web es fundamentalmente para
                         humanos (HTML)
<table width="100%" cellspacing="1" cellpadding="1" border="0" align="center">
<tbody>
          <tr>
            <td valign="middle" align="center" colspan="5">
          </td></tr><tr>
            <td align="center" class="cabe"> Hora Salida </td>
            <td align="center" class="cabe"> Hora Llegada </td>
            <td align="center" class="cabe"> Línea </td>
            <td align="center" class="cabe"> Tiempo de Viaje </td>
            <td align="center" class="cabe"> </td>
          </tr>

           <tr>
...
             <td   align="center" class="color1">06.39</td>
             <td   align="center" class="color2">07.15</td>
             <td   class="color3">C1 </td>
             <td   align="center" class="color1">0.36</td>
             <td   align="center" class="rojo3"> </td>
           </tr>
</tbody>
Porqué screen scraping
  La Web es fundamentalmente para
         humanos (HTML)
Porqué screen scraping
   La Web es fundamentalmente para
          humanos (HTML)

Pero no está diseñada para ser procesada
   por máquinas (XML, JSON, CSV...)
Porqué screen scraping
    La Web es fundamentalmente para
           humanos (HTML)

Pero no está diseñada para ser procesada
   por máquinas (XML, JSON, CSV...)

<horario>
    <viaje>
        <salida format="hh:mm">06:39</salida>
        <llegada format="hh:mm">07:15</llegada>
        <duracion format="minutes">36</duracion>
        <linea>C1</linea>
    </viaje>
</horario>
Porqué screen scraping
 No siempre disponemos de una API
Porqué screen scraping
    No siempre disponemos de una API




Necesitamos simular el comportamiento humano
Porqué screen scraping
    No siempre disponemos de una API




Necesitamos simular el comportamiento humano


 Interpretar
    HTML
Porqué screen scraping
    No siempre disponemos de una API




Necesitamos simular el comportamiento humano


                   Realizar
 Interpretar
                interacciones
    HTML
                  (Navegar)
Porqué screen scraping
    No siempre disponemos de una API




Necesitamos simular el comportamiento humano


                   Realizar
 Interpretar
                interacciones   Ser un Ninja
    HTML
                  (Navegar)
                                           Evitar DoS
Selección de las herramientas
                ¿Con qué lenguaje vamos a trabajar?

                      Java                   .NET               Ruby           Python

                                                                net/http
   URL                                    System.Net.                           urllib
                  java.net.URL                                 open-uri
 fetching                               HTTPWebRequest                          urllib2
                                                             rest-open-uri
    DOM         javax.swing.text.html                        HTree / ReXML
   parsing          TagSoup
      /
                                        HTMLAgilityPack         HPricot      BeautifulSoup
                   NekoHTML                                   RubyfulSoup
transversing


                                           System.Text.
 Regexp         java.util.regexp        RegularExpressions
                                                                Regexp            re


  --- Librerías de terceras partes. No forman parte de la API del lenguaje.
Selección de las herramientas


       ¿Con qué lenguaje vamos a trabajar?



    Duck typing + Reflexión = Syntactic Sugar
Selección de las herramientas


       ¿Con qué lenguaje vamos a trabajar?

      Lenguajes dinámicos facilitan la codificación


    Duck typing + Reflexión = Syntactic Sugar
Java
import     javax.swing.text.html.*;
import     javax.swing.text.Element;
import     javax.swing.text.ElementIterator;
import     java.net.URL;
import     java.io.InputStreamReader;
import     java.io.Reader;

public class HTMLParser
{
  public static void main( String[] argv ) throws Exception
  {
    URL url = new URL( "http://java.sun.com" );
    HTMLEditorKit kit = new HTMLEditorKit();
    HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
    doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
    Reader HTMLReader = new InputStreamReader(url.openConnection().getInputStream());
    kit.read(HTMLReader, doc, 0);

        ElementIterator it = new ElementIterator(doc);
        Element elem;

        while( elem = it.next() != null )
        {
          if( elem.getName().equals( "img") )
          {
            String s = (String) elem.getAttributes().getAttribute(HTML.Attribute.SRC);
            if( s != null )
              System.out.println (s );
          }
        }
        System.exit(0);
    }
}
Ruby
require   'rubygems'
require   'open-uri'
require   'htree'
require   'rexml/document'

 open("http://java.sun.com",:proxy=>"http://localhost:8080") do |page|
     page_content = page.read()
     doc = HTree(page_content).to_rexml
     doc.root.each_element('//img') {|elem| puts elem.attribute('src').value }
 end
Selección de las herramientas                  Ruby
 rest-open-uri
                 Nos permitirá hacer peticiones a
HTree + REXML     URLs y extraer su contenido
    Hpricot
                 extiende open-uri para soportar
  RubyfulSoup              más verbos
WWW:Mechanize
Selección de las herramientas                 Ruby
                  HTree crea un árbol de
 rest-open-uri   objetos a partir de código
                           HTML
HTree + REXML

    Hpricot
                    HTree#to_rexml
                 Convierte el árbol a un árbol
  RubyfulSoup              REXML
WWW:Mechanize    REXML puede navegarse con
                        XPath 2.0
HTree+REXML
require   'rubygems'
require   'open-uri'
require   'htree'
require   'rexml/document'

 open("http://www.google.es/search?q=ruby",:proxy=>"http://localhost:8080") do |page|
     page_content = page.read()
     doc = HTree(page_content).to_rexml
     doc.root.each_element('//a[@class=l]') {|elem| puts elem.attribute('href').value }
 end




                                 Runtime: 7.06s.
Selección de las herramientas                         Ruby
                               Scanner implementado en C
 rest-open-uri
                                      (Muy rápido)
HTree + REXML
                             Genera un DOM con su
    Hpricot                propio sistema de navegación
  RubyfulSoup    como Jquery(selectores CSS y XPath*)

WWW:Mechanize                   Funcionalidad equivalente a
                                     Htree + REXML

                   http://hpricot.com/
HPricot

require 'rubygems'
require 'hpricot'
require 'open-uri'

doc = Hpricot(open('http://www.google.com/search?q=ruby',:proxy=>'http://localhost:8080'))
links = doc/"//a[@class=l]"
links.map.each {|link| puts link.attributes['href']}




                                  Runtime: 3.71s
Selección de las herramientas                         Ruby
                            Scanner implementado en C
 rest-open-uri
                                   (Muy rápido)
HTree + REXML
                             Genera un DOM con su
    Hpricot                propio sistema de navegación
  RubyfulSoup    co mo Jquery
                            (selectores CSS y XPath*)

WWW:Mechanize                   Funcionalidad equivalente a
                                     Htree + REXML

                  http://hpricot.com/
Selección de las herramientas                         Ruby
                            Scanner implementado en C
 rest-open-uri
                                   (Muy rápido)
    Hpricot
                             Genera un DOM con su
  RubyfulSoup              propio sistema de navegación
WWW:Mechanize    co mo Jquery
                            (selectores CSS y XPath*)

                                Funcionalidad equivalente a
                                     Htree + REXML

                  http://hpricot.com/
Selección de las herramientas                Ruby
 rest-open-uri
                 Ofrece la misma funcionalidad que
    Hpricot              HTree + REXML
  RubyfulSoup

WWW:Mechanize
Rubyful Soup
require 'rubygems'
require 'rubyful_soup'
require 'open-uri'

open("http://www.google.com/search?q=ruby",:proxy=>"http://localhost:8080") do |page|
  page_content = page.read()
  soup = BeautifulSoup.new(page_content)
  result = soup.find_all('a', :attrs => {'class' => 'l'})
  result.each { |tag| puts tag['href'] }
end




                                Runtime: 4.71s
Selección de las herramientas                Ruby
 rest-open-uri
                 Ofrece la misma funcionalidad que
    Hpricot              HTree + REXML
  RubyfulSoup

WWW:Mechanize
Selección de las herramientas                Ruby
 rest-open-uri
                 Ofrece la misma funcionalidad que
    Hpricot              HTree + REXML
  RubyfulSoup     Menor rendimiento que Hpricot
WWW:Mechanize
Selección de las herramientas                Ruby
 rest-open-uri
                 Ofrece la misma funcionalidad que
    Hpricot              HTree + REXML
  RubyfulSoup     Menor rendimiento que Hpricot
WWW:Mechanize      No se admiten selectores CSS
Selección de las herramientas                Ruby
                 Ofrece la misma funcionalidad que
 rest-open-uri           HTree + REXML

   Hpricot        Menor rendimiento que Hpricot
WWW:Mechanize      No se admiten selectores CSS
Selección de las herramientas                      Ruby
                 Permite realizar interacciones
 rest-open-uri
                       Rellenar y enviar formularios
   Hpricot             Seguir enlaces

WWW:Mechanize    Consigue alcanzar documentos en
                 La Web Profunda
WWW::Mechanize
require 'rubygems'
require 'mechanize'

agent = Mechanize.new
agent.set_proxy("localhost",8080)
page = agent.get('http://www.google.com')

search_form = page.forms.select{|f| f.name=="f"}.first
search_form.fields.select {|f| f.name=='q'}.first.value="ruby"
search_results = agent.submit(search_form)
search_results.links.each { |link| puts link.href if link.attributes["class"] == "l" }




                                Runtime: 5.23s
Manos a la obra
No tiene API pública

>8000 usuarios nuevos cada día

   2h de sesión promedio

   datos datos datos!
Novedades de tuenti
Paso 1: Acceder a nuestro perfil
require 'rubygems'
require 'mechanize'

agent = Mechanize.new
agent.set_proxy("localhost",8080)
#decimos que somos firefox modificando la cabecera user agent
agent.user_agent_alias='Mac FireFox'
login_page = agent.get('http://m.tuenti.com/?m=login')

#cogemos el formulario de login
login_form = login_page.forms.first
#y rellenamos los campos usuario y contraseña
login_form.fields.select{|f| f.name=="email"}.first.value="miguelfernandezfernandez@gmail.com"
login_form.fields.select{|f| f.name=="input_password"}.first.value="xxxxx"

pagina_de_inicio?=agent.submit(login_form)
Redirecciona por Javascript
Segundo intento: versión móvil
       require 'rubygems'
       require 'mechanize'

       agent = Mechanize.new
       agent.set_proxy("localhost",8080)
       #decimos que somos firefox modificando la cabecera user agent
       agent.user_agent_alias='Mac FireFox'
       login_page = agent.get('http://m.tuenti.com/?m=login')

       #cogemos el formulario de login
       login_form = login_page.forms.first
       #y rellenamos los campos usuario y contraseña
       login_form.fields.select{|f|
       f.name=="tuentiemail"}.first.value="miguelfernandezfernandez@gmail.com
       "
       login_form.fields.select{|f| f.name=="password"}.first.value="xxxxxx"

       pagina_de_inicio=agent.submit(login_form)
Eureka!
require 'rubygems'
require 'mechanize'



class TuentiAPI

  def initialize(login,password)
    @login=login
    @password=password
  end

  def inicio()
    agent = Mechanize.new
    agent.set_proxy("localhost",8080)
    #decimos que somos firefox modificando la cabecera user agent
    agent.user_agent_alias='Mac FireFox'
    login_page = agent.get('http://m.tuenti.com/?m=login')

      #cogemos el formulario de login
      login_form = login_page.forms.first
      #y rellenamos los campos usuario y contraseña
      login_form.fields.select{|f| f.name=="tuentiemail"}.first.value=@login
      login_form.fields.select{|f| f.name=="password"}.first.value=@password

    pagina_de_inicio=agent.submit(login_form)
  end

end



pagina_de_inicio=TuentiAPI.new("miguelfernandezfernandez@gmail.com","xxxxxx").inicio()
Paso 2: Obtener las fotos
<div class=”box”>


<div class=”box”>


<div class=”box”>
Paso 2: Obtener las fotos
class TuentiAPI

...

  def fotos_nuevas()
     tree=Hpricot(inicio().content)
     fotos = tree / "//a//img[@alt=Foto]"
     fotos.map!{|foto| foto.attributes["src"]}
     Set.new(fotos).to_a
   end

  private

  def inicio()
  ...
  end
end
Paso 3: Establecer el estado
Paso 3: Establecer el estado


class TuentiAPI
   ...

      def actualizar_estado(msg)
        form_actualizacion=inicio.forms.first
        form_actualizacion.fields.select{|f| f.name=="status"}.first.value=msg
        @agent.submit(form_actualizacion)
      end

end
Ninja Moves
Tor: navegando de forma
        anónima
    Red de encadenamiento de proxies

   N peticiones salen de M servidores
    Garantiza el anonimato a nivel de IP




  https://www.torproject.org/vidalia/
Gracias
Universidad de Oviedo   Programa de extensión universitaria




     CLOUD COMPUTING.
DESARROLLO DE APLICACIONES Y
        MINERÍA WEB


                               Miguel Fernández Fernández
                                miguelff@innova.uniovi.es

Mais conteúdo relacionado

Semelhante a Screen scraping

Diferentes lenguajes de programación web
Diferentes lenguajes de programación webDiferentes lenguajes de programación web
Diferentes lenguajes de programación web
Xoch Flores
 
Ajax
AjaxAjax
Ajax
utpl
 
Conceptos acerca de Ajax
Conceptos acerca  de AjaxConceptos acerca  de Ajax
Conceptos acerca de Ajax
Alvaro Castillo
 
Introduccion Ajax V1.0
Introduccion Ajax V1.0Introduccion Ajax V1.0
Introduccion Ajax V1.0
Arnulfo Gomez
 
Ruby On Rails Jun2009
Ruby On Rails Jun2009Ruby On Rails Jun2009
Ruby On Rails Jun2009
Sergio Alonso
 

Semelhante a Screen scraping (20)

Screen scraping
Screen scrapingScreen scraping
Screen scraping
 
Ajax
AjaxAjax
Ajax
 
AJAX EN CURSO PHP
AJAX EN CURSO PHPAJAX EN CURSO PHP
AJAX EN CURSO PHP
 
Barcelona Workshop 2008
Barcelona Workshop 2008Barcelona Workshop 2008
Barcelona Workshop 2008
 
Diferentes lenguajes de programación web
Diferentes lenguajes de programación webDiferentes lenguajes de programación web
Diferentes lenguajes de programación web
 
Presentacion Ruby on Rails en Universidad Autónoma 2009
Presentacion Ruby on Rails en Universidad Autónoma 2009Presentacion Ruby on Rails en Universidad Autónoma 2009
Presentacion Ruby on Rails en Universidad Autónoma 2009
 
Ajax
AjaxAjax
Ajax
 
Inicios Ajax
Inicios AjaxInicios Ajax
Inicios Ajax
 
Ajax
AjaxAjax
Ajax
 
Conceptos acerca de Ajax
Conceptos acerca  de AjaxConceptos acerca  de Ajax
Conceptos acerca de Ajax
 
La web como Plataforma con Dojo Toolkit
La web como Plataforma con Dojo ToolkitLa web como Plataforma con Dojo Toolkit
La web como Plataforma con Dojo Toolkit
 
Introduccion Ajax V1.0
Introduccion Ajax V1.0Introduccion Ajax V1.0
Introduccion Ajax V1.0
 
Ajax
AjaxAjax
Ajax
 
Introducción a JQuery
Introducción a JQueryIntroducción a JQuery
Introducción a JQuery
 
Conceptos Introductorios Del Web 2
Conceptos Introductorios Del Web 2Conceptos Introductorios Del Web 2
Conceptos Introductorios Del Web 2
 
ROA - Resource Oriented Architecture
ROA - Resource Oriented ArchitectureROA - Resource Oriented Architecture
ROA - Resource Oriented Architecture
 
API REST conceptos (Rails-api)
API REST conceptos (Rails-api)API REST conceptos (Rails-api)
API REST conceptos (Rails-api)
 
Charla
CharlaCharla
Charla
 
Ruby On Rails Jun2009
Ruby On Rails Jun2009Ruby On Rails Jun2009
Ruby On Rails Jun2009
 
Curso de HTML5
Curso de HTML5Curso de HTML5
Curso de HTML5
 

Mais de Miguel Fernández (6)

Hierarchical taxonomy extraction
Hierarchical taxonomy extractionHierarchical taxonomy extraction
Hierarchical taxonomy extraction
 
Yahoo! pipes
Yahoo! pipesYahoo! pipes
Yahoo! pipes
 
Real-time web
Real-time webReal-time web
Real-time web
 
App engine
App engineApp engine
App engine
 
Ruby intro
Ruby introRuby intro
Ruby intro
 
Rails intro
Rails introRails intro
Rails intro
 

Último

Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
AnnimoUno1
 

Último (11)

Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
 
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 

Screen scraping

  • 1. Universidad de Oviedo Programa de extensión universitaria CLOUD COMPUTING. DESARROLLO DE APLICACIONES Y MINERÍA WEB Miguel Fernández Fernández miguelff@innova.uniovi.es
  • 3. Porqué screen scraping La Web es fundamentalmente para humanos (HTML)
  • 4. Porqué screen scraping La Web es fundamentalmente para humanos (HTML)
  • 5. Porqué screen scraping La Web es fundamentalmente para humanos (HTML) <table width="100%" cellspacing="1" cellpadding="1" border="0" align="center"> <tbody> <tr> <td valign="middle" align="center" colspan="5"> </td></tr><tr> <td align="center" class="cabe"> Hora Salida </td> <td align="center" class="cabe"> Hora Llegada </td> <td align="center" class="cabe"> Línea </td> <td align="center" class="cabe"> Tiempo de Viaje </td> <td align="center" class="cabe"> </td> </tr> <tr> ... <td align="center" class="color1">06.39</td> <td align="center" class="color2">07.15</td> <td class="color3">C1 </td> <td align="center" class="color1">0.36</td> <td align="center" class="rojo3"> </td> </tr> </tbody>
  • 6. Porqué screen scraping La Web es fundamentalmente para humanos (HTML)
  • 7. Porqué screen scraping La Web es fundamentalmente para humanos (HTML) Pero no está diseñada para ser procesada por máquinas (XML, JSON, CSV...)
  • 8. Porqué screen scraping La Web es fundamentalmente para humanos (HTML) Pero no está diseñada para ser procesada por máquinas (XML, JSON, CSV...) <horario> <viaje> <salida format="hh:mm">06:39</salida> <llegada format="hh:mm">07:15</llegada> <duracion format="minutes">36</duracion> <linea>C1</linea> </viaje> </horario>
  • 9. Porqué screen scraping No siempre disponemos de una API
  • 10. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano
  • 11. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano Interpretar HTML
  • 12. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano Realizar Interpretar interacciones HTML (Navegar)
  • 13. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano Realizar Interpretar interacciones Ser un Ninja HTML (Navegar) Evitar DoS
  • 14. Selección de las herramientas ¿Con qué lenguaje vamos a trabajar? Java .NET Ruby Python net/http URL System.Net. urllib java.net.URL open-uri fetching HTTPWebRequest urllib2 rest-open-uri DOM javax.swing.text.html HTree / ReXML parsing TagSoup / HTMLAgilityPack HPricot BeautifulSoup NekoHTML RubyfulSoup transversing System.Text. Regexp java.util.regexp RegularExpressions Regexp re --- Librerías de terceras partes. No forman parte de la API del lenguaje.
  • 15. Selección de las herramientas ¿Con qué lenguaje vamos a trabajar? Duck typing + Reflexión = Syntactic Sugar
  • 16. Selección de las herramientas ¿Con qué lenguaje vamos a trabajar? Lenguajes dinámicos facilitan la codificación Duck typing + Reflexión = Syntactic Sugar
  • 17. Java import javax.swing.text.html.*; import javax.swing.text.Element; import javax.swing.text.ElementIterator; import java.net.URL; import java.io.InputStreamReader; import java.io.Reader; public class HTMLParser { public static void main( String[] argv ) throws Exception { URL url = new URL( "http://java.sun.com" ); HTMLEditorKit kit = new HTMLEditorKit(); HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE); Reader HTMLReader = new InputStreamReader(url.openConnection().getInputStream()); kit.read(HTMLReader, doc, 0); ElementIterator it = new ElementIterator(doc); Element elem; while( elem = it.next() != null ) { if( elem.getName().equals( "img") ) { String s = (String) elem.getAttributes().getAttribute(HTML.Attribute.SRC); if( s != null ) System.out.println (s ); } } System.exit(0); } }
  • 18. Ruby require 'rubygems' require 'open-uri' require 'htree' require 'rexml/document' open("http://java.sun.com",:proxy=>"http://localhost:8080") do |page| page_content = page.read() doc = HTree(page_content).to_rexml doc.root.each_element('//img') {|elem| puts elem.attribute('src').value } end
  • 19. Selección de las herramientas Ruby rest-open-uri Nos permitirá hacer peticiones a HTree + REXML URLs y extraer su contenido Hpricot extiende open-uri para soportar RubyfulSoup más verbos WWW:Mechanize
  • 20. Selección de las herramientas Ruby HTree crea un árbol de rest-open-uri objetos a partir de código HTML HTree + REXML Hpricot HTree#to_rexml Convierte el árbol a un árbol RubyfulSoup REXML WWW:Mechanize REXML puede navegarse con XPath 2.0
  • 21. HTree+REXML require 'rubygems' require 'open-uri' require 'htree' require 'rexml/document' open("http://www.google.es/search?q=ruby",:proxy=>"http://localhost:8080") do |page| page_content = page.read() doc = HTree(page_content).to_rexml doc.root.each_element('//a[@class=l]') {|elem| puts elem.attribute('href').value } end Runtime: 7.06s.
  • 22. Selección de las herramientas Ruby Scanner implementado en C rest-open-uri (Muy rápido) HTree + REXML Genera un DOM con su Hpricot propio sistema de navegación RubyfulSoup como Jquery(selectores CSS y XPath*) WWW:Mechanize Funcionalidad equivalente a Htree + REXML http://hpricot.com/
  • 23. HPricot require 'rubygems' require 'hpricot' require 'open-uri' doc = Hpricot(open('http://www.google.com/search?q=ruby',:proxy=>'http://localhost:8080')) links = doc/"//a[@class=l]" links.map.each {|link| puts link.attributes['href']} Runtime: 3.71s
  • 24. Selección de las herramientas Ruby Scanner implementado en C rest-open-uri (Muy rápido) HTree + REXML Genera un DOM con su Hpricot propio sistema de navegación RubyfulSoup co mo Jquery (selectores CSS y XPath*) WWW:Mechanize Funcionalidad equivalente a Htree + REXML http://hpricot.com/
  • 25. Selección de las herramientas Ruby Scanner implementado en C rest-open-uri (Muy rápido) Hpricot Genera un DOM con su RubyfulSoup propio sistema de navegación WWW:Mechanize co mo Jquery (selectores CSS y XPath*) Funcionalidad equivalente a Htree + REXML http://hpricot.com/
  • 26. Selección de las herramientas Ruby rest-open-uri Ofrece la misma funcionalidad que Hpricot HTree + REXML RubyfulSoup WWW:Mechanize
  • 27. Rubyful Soup require 'rubygems' require 'rubyful_soup' require 'open-uri' open("http://www.google.com/search?q=ruby",:proxy=>"http://localhost:8080") do |page| page_content = page.read() soup = BeautifulSoup.new(page_content) result = soup.find_all('a', :attrs => {'class' => 'l'}) result.each { |tag| puts tag['href'] } end Runtime: 4.71s
  • 28. Selección de las herramientas Ruby rest-open-uri Ofrece la misma funcionalidad que Hpricot HTree + REXML RubyfulSoup WWW:Mechanize
  • 29. Selección de las herramientas Ruby rest-open-uri Ofrece la misma funcionalidad que Hpricot HTree + REXML RubyfulSoup Menor rendimiento que Hpricot WWW:Mechanize
  • 30. Selección de las herramientas Ruby rest-open-uri Ofrece la misma funcionalidad que Hpricot HTree + REXML RubyfulSoup Menor rendimiento que Hpricot WWW:Mechanize No se admiten selectores CSS
  • 31. Selección de las herramientas Ruby Ofrece la misma funcionalidad que rest-open-uri HTree + REXML Hpricot Menor rendimiento que Hpricot WWW:Mechanize No se admiten selectores CSS
  • 32. Selección de las herramientas Ruby Permite realizar interacciones rest-open-uri Rellenar y enviar formularios Hpricot Seguir enlaces WWW:Mechanize Consigue alcanzar documentos en La Web Profunda
  • 33. WWW::Mechanize require 'rubygems' require 'mechanize' agent = Mechanize.new agent.set_proxy("localhost",8080) page = agent.get('http://www.google.com') search_form = page.forms.select{|f| f.name=="f"}.first search_form.fields.select {|f| f.name=='q'}.first.value="ruby" search_results = agent.submit(search_form) search_results.links.each { |link| puts link.href if link.attributes["class"] == "l" } Runtime: 5.23s
  • 34. Manos a la obra
  • 35. No tiene API pública >8000 usuarios nuevos cada día 2h de sesión promedio datos datos datos!
  • 37. Paso 1: Acceder a nuestro perfil require 'rubygems' require 'mechanize' agent = Mechanize.new agent.set_proxy("localhost",8080) #decimos que somos firefox modificando la cabecera user agent agent.user_agent_alias='Mac FireFox' login_page = agent.get('http://m.tuenti.com/?m=login') #cogemos el formulario de login login_form = login_page.forms.first #y rellenamos los campos usuario y contraseña login_form.fields.select{|f| f.name=="email"}.first.value="miguelfernandezfernandez@gmail.com" login_form.fields.select{|f| f.name=="input_password"}.first.value="xxxxx" pagina_de_inicio?=agent.submit(login_form)
  • 39. Segundo intento: versión móvil require 'rubygems' require 'mechanize' agent = Mechanize.new agent.set_proxy("localhost",8080) #decimos que somos firefox modificando la cabecera user agent agent.user_agent_alias='Mac FireFox' login_page = agent.get('http://m.tuenti.com/?m=login') #cogemos el formulario de login login_form = login_page.forms.first #y rellenamos los campos usuario y contraseña login_form.fields.select{|f| f.name=="tuentiemail"}.first.value="miguelfernandezfernandez@gmail.com " login_form.fields.select{|f| f.name=="password"}.first.value="xxxxxx" pagina_de_inicio=agent.submit(login_form)
  • 41. require 'rubygems' require 'mechanize' class TuentiAPI def initialize(login,password) @login=login @password=password end def inicio() agent = Mechanize.new agent.set_proxy("localhost",8080) #decimos que somos firefox modificando la cabecera user agent agent.user_agent_alias='Mac FireFox' login_page = agent.get('http://m.tuenti.com/?m=login') #cogemos el formulario de login login_form = login_page.forms.first #y rellenamos los campos usuario y contraseña login_form.fields.select{|f| f.name=="tuentiemail"}.first.value=@login login_form.fields.select{|f| f.name=="password"}.first.value=@password pagina_de_inicio=agent.submit(login_form) end end pagina_de_inicio=TuentiAPI.new("miguelfernandezfernandez@gmail.com","xxxxxx").inicio()
  • 42. Paso 2: Obtener las fotos
  • 44.
  • 45. Paso 2: Obtener las fotos class TuentiAPI ... def fotos_nuevas() tree=Hpricot(inicio().content) fotos = tree / "//a//img[@alt=Foto]" fotos.map!{|foto| foto.attributes["src"]} Set.new(fotos).to_a end private def inicio() ... end end
  • 46. Paso 3: Establecer el estado
  • 47.
  • 48. Paso 3: Establecer el estado class TuentiAPI ... def actualizar_estado(msg) form_actualizacion=inicio.forms.first form_actualizacion.fields.select{|f| f.name=="status"}.first.value=msg @agent.submit(form_actualizacion) end end
  • 50. Tor: navegando de forma anónima Red de encadenamiento de proxies N peticiones salen de M servidores Garantiza el anonimato a nivel de IP https://www.torproject.org/vidalia/
  • 52. Universidad de Oviedo Programa de extensión universitaria CLOUD COMPUTING. DESARROLLO DE APLICACIONES Y MINERÍA WEB Miguel Fernández Fernández miguelff@innova.uniovi.es