SlideShare une entreprise Scribd logo
1  sur  52
CLOUD COMPUTING.
DESARROLLO DE APLICACIONESY
MINERÍA WEB
Programa de extensión universitariaUniversidad de Oviedo
Miguel Fernández Fernández
miguel@ThirdWay.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
Interpretar
HTML
Realizar
interacciones
(Navegar)
Porqué screen scraping
No siempre disponemos de una API
Necesitamos simular el comportamiento humano
Interpretar
HTML
Realizar
interacciones
(Navegar)
Ser un Ninja
Evitar DoS
Selección de las herramientas
¿Con qué lenguaje vamos a trabajar?
Java .NET Ruby Python
URL
fetching
java.net.URL
System.Net.
HTTPWebRequest
net/http
open-uri
rest-open-uri
urllib
urllib2
DOM
parsing
/
transversing
javax.swing.text.html
TagSoup
NekoHTML
HTMLAgilityPack
HTree / ReXML
HPricot
RubyfulSoup
BeautifulSoup
Regexp java.util.regexp
System.Text.
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
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);
}
}
Java
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 RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
Nos permitirá hacer peticiones a
URLs y extraer su contenido
extiende open-uri para soportar
más verbos
Selección de las herramientas RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
HTree crea un árbol de
objetos a partir de código
HTML
HTree#to_rexml
Convierte el árbol a un árbol
REXML
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 RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
http://hpricot.com/
Scanner implementado en C
(Muy rápido)
Genera un DOM con su
propio sistema de navegación
(selectores CSS y XPath*)como Jquery
Funcionalidad equivalente a
Htree + REXML
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 RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
http://hpricot.com/
Scanner implementado en C
(Muy rápido)
Genera un DOM con su
propio sistema de navegación
(selectores CSS y XPath*)como Jquery
Funcionalidad equivalente a
Htree + REXML
Selección de las herramientas RubyRuby
rest-open-uri
RubyfulSoup
WWW:Mechanize
Hpricot
http://hpricot.com/
Scanner implementado en C
(Muy rápido)
Genera un DOM con su
propio sistema de navegación
(selectores CSS y XPath*)como Jquery
Funcionalidad equivalente a
Htree + REXML
Selección de las herramientas RubyRuby
rest-open-uri
RubyfulSoup
WWW:Mechanize
Hpricot
Ofrece la misma funcionalidad que
HTree + REXML
Rubyful Soup
Runtime: 4.71s
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
Selección de las herramientas RubyRuby
RubyfulSoup
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
HTree + REXML
Selección de las herramientas RubyRuby
RubyfulSoup
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
HTree + REXML
Menor rendimiento que Hpricot
Selección de las herramientas RubyRuby
RubyfulSoup
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
HTree + REXML
Menor rendimiento que Hpricot
No se admiten selectores CSS
Selección de las herramientas RubyRuby
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
HTree + REXML
Menor rendimiento que Hpricot
No se admiten selectores CSS
Selección de las herramientas RubyRuby
rest-open-uri
WWW:Mechanize
Hpricot
Permite realizar interacciones
Rellenar y enviar formularios
Seguir enlaces
Consigue alcanzar documentos en
La Web Profunda
WWW::Mechanize
Runtime: 5.23s
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" }
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
https://www.torproject.org/vidalia/
Red de encadenamiento de proxies
N peticiones salen de M servidores
Garantiza el anonimato a nivel de IP
Gracias
CLOUD COMPUTING.
DESARROLLO DE APLICACIONESY
MINERÍA WEB
Programa de extensión universitariaUniversidad de Oviedo
Miguel Fernández Fernández
miguel@ThirdWay.es

Contenu connexe

Similaire à Screen scraping

Similaire à Screen scraping (20)

Screen scraping
Screen scrapingScreen scraping
Screen scraping
 
Curso de HTML5
Curso de HTML5Curso de HTML5
Curso de HTML5
 
Open Source Modern Web Development
Open Source Modern Web DevelopmentOpen Source Modern Web Development
Open Source Modern Web Development
 
Prueba De Aplicaciones Web con Selenium 2 y WebDriver
Prueba De Aplicaciones Web con Selenium 2 y WebDriverPrueba De Aplicaciones Web con Selenium 2 y WebDriver
Prueba De Aplicaciones Web con Selenium 2 y WebDriver
 
Seminario jquery, html5 y wicket
Seminario jquery, html5 y wicketSeminario jquery, html5 y wicket
Seminario jquery, html5 y wicket
 
Mootools Y Otros Frameworks JS
Mootools Y Otros Frameworks JSMootools Y Otros Frameworks JS
Mootools Y Otros Frameworks JS
 
(Muy breve) Introduccion a jQuery
(Muy breve) Introduccion a jQuery(Muy breve) Introduccion a jQuery
(Muy breve) Introduccion a jQuery
 
Curso de Desarrollo Web de Platzi
Curso de Desarrollo Web de PlatziCurso de Desarrollo Web de Platzi
Curso de Desarrollo Web de Platzi
 
Ajax
AjaxAjax
Ajax
 
Introducción a JQuery
Introducción a JQueryIntroducción a JQuery
Introducción a JQuery
 
Acceso a BBDD mediante un servlet
Acceso a BBDD mediante un servletAcceso a BBDD mediante un servlet
Acceso a BBDD mediante un servlet
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
Tema servlets
Tema servletsTema servlets
Tema servlets
 
HTML5
HTML5HTML5
HTML5
 
Apuntes php
Apuntes phpApuntes php
Apuntes php
 
myprofly
myproflymyprofly
myprofly
 
Servicios web
Servicios webServicios web
Servicios web
 
01 Ext Js Introduccion
01 Ext Js   Introduccion01 Ext Js   Introduccion
01 Ext Js Introduccion
 

Dernier

Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíassuserf18419
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricKeyla Dolores Méndez
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxHernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxJOSEMANUELHERNANDEZH11
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxpabonheidy28
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024GiovanniJavierHidalg
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx241521559
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfsoporteupcology
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)GDGSucre
 
9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudianteAndreaHuertas24
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafiosFundación YOD YOD
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan JosephBRAYANJOSEPHPEREZGOM
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesFundación YOD YOD
 
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE  DE TECNOLOGIA E INFORMATICA PRIMARIACLASE  DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIAWilbisVega
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...silviayucra2
 

Dernier (16)

Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnología
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxHernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptx
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docx
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdf
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)
 
9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafios
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Joseph
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento Protégeles
 
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE  DE TECNOLOGIA E INFORMATICA PRIMARIACLASE  DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
 

Screen scraping

  • 1. CLOUD COMPUTING. DESARROLLO DE APLICACIONESY MINERÍA WEB Programa de extensión universitariaUniversidad de Oviedo Miguel Fernández Fernández miguel@ThirdWay.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 Interpretar HTML Realizar interacciones (Navegar)
  • 13. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano Interpretar HTML Realizar interacciones (Navegar) Ser un Ninja Evitar DoS
  • 14. Selección de las herramientas ¿Con qué lenguaje vamos a trabajar? Java .NET Ruby Python URL fetching java.net.URL System.Net. HTTPWebRequest net/http open-uri rest-open-uri urllib urllib2 DOM parsing / transversing javax.swing.text.html TagSoup NekoHTML HTMLAgilityPack HTree / ReXML HPricot RubyfulSoup BeautifulSoup Regexp java.util.regexp System.Text. 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. 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); } } Java
  • 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 RubyRuby rest-open-uri HTree + REXML RubyfulSoup WWW:Mechanize Hpricot Nos permitirá hacer peticiones a URLs y extraer su contenido extiende open-uri para soportar más verbos
  • 20. Selección de las herramientas RubyRuby rest-open-uri HTree + REXML RubyfulSoup WWW:Mechanize Hpricot HTree crea un árbol de objetos a partir de código HTML HTree#to_rexml Convierte el árbol a un árbol REXML 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 RubyRuby rest-open-uri HTree + REXML RubyfulSoup WWW:Mechanize Hpricot http://hpricot.com/ Scanner implementado en C (Muy rápido) Genera un DOM con su propio sistema de navegación (selectores CSS y XPath*)como Jquery Funcionalidad equivalente a Htree + REXML
  • 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 RubyRuby rest-open-uri HTree + REXML RubyfulSoup WWW:Mechanize Hpricot http://hpricot.com/ Scanner implementado en C (Muy rápido) Genera un DOM con su propio sistema de navegación (selectores CSS y XPath*)como Jquery Funcionalidad equivalente a Htree + REXML
  • 25. Selección de las herramientas RubyRuby rest-open-uri RubyfulSoup WWW:Mechanize Hpricot http://hpricot.com/ Scanner implementado en C (Muy rápido) Genera un DOM con su propio sistema de navegación (selectores CSS y XPath*)como Jquery Funcionalidad equivalente a Htree + REXML
  • 26. Selección de las herramientas RubyRuby rest-open-uri RubyfulSoup WWW:Mechanize Hpricot Ofrece la misma funcionalidad que HTree + REXML
  • 27. Rubyful Soup Runtime: 4.71s 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
  • 28. Selección de las herramientas RubyRuby RubyfulSoup WWW:Mechanize rest-open-uri Hpricot Ofrece la misma funcionalidad que HTree + REXML
  • 29. Selección de las herramientas RubyRuby RubyfulSoup WWW:Mechanize rest-open-uri Hpricot Ofrece la misma funcionalidad que HTree + REXML Menor rendimiento que Hpricot
  • 30. Selección de las herramientas RubyRuby RubyfulSoup WWW:Mechanize rest-open-uri Hpricot Ofrece la misma funcionalidad que HTree + REXML Menor rendimiento que Hpricot No se admiten selectores CSS
  • 31. Selección de las herramientas RubyRuby WWW:Mechanize rest-open-uri Hpricot Ofrece la misma funcionalidad que HTree + REXML Menor rendimiento que Hpricot No se admiten selectores CSS
  • 32. Selección de las herramientas RubyRuby rest-open-uri WWW:Mechanize Hpricot Permite realizar interacciones Rellenar y enviar formularios Seguir enlaces Consigue alcanzar documentos en La Web Profunda
  • 33. WWW::Mechanize Runtime: 5.23s 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" }
  • 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 https://www.torproject.org/vidalia/ Red de encadenamiento de proxies N peticiones salen de M servidores Garantiza el anonimato a nivel de IP
  • 52. CLOUD COMPUTING. DESARROLLO DE APLICACIONESY MINERÍA WEB Programa de extensión universitariaUniversidad de Oviedo Miguel Fernández Fernández miguel@ThirdWay.es