CLOUD COMPUTING.
DESARROLLO DE APLICACIONESY
MINERÍA WEB
Programa de extensión universitariaUniversidad de Oviedo
Miguel F...
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" ...
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áquina...
Porqué screen scraping
La Web es fundamentalmente para
humanos (HTML)
Pero no está diseñada para ser procesada
por máquina...
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
Real...
Porqué screen scraping
No siempre disponemos de una API
Necesitamos simular el comportamiento humano
Interpretar
HTML
Real...
Selección de las herramientas
¿Con qué lenguaje vamos a trabajar?
Java .NET Ruby Python
URL
fetching
java.net.URL
System.N...
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...
import javax.swing.text.html.*;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import java.net....
Ruby
require 'rubygems'
require 'open-uri'
require 'htree'
require 'rexml/document'
open("http://java.sun.com",:proxy=>"ht...
Selección de las herramientas RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
Nos permitirá hacer p...
Selección de las herramientas RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
HTree crea un árbol d...
HTree+REXML
require 'rubygems'
require 'open-uri'
require 'htree'
require 'rexml/document'
open("http://www.google.es/sear...
Selección de las herramientas RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
http://hpricot.com/
S...
HPricot
require 'rubygems'
require 'hpricot'
require 'open-uri'
doc = Hpricot(open('http://www.google.com/search?q=ruby',:...
Selección de las herramientas RubyRuby
rest-open-uri
HTree + REXML
RubyfulSoup
WWW:Mechanize
Hpricot
http://hpricot.com/
S...
Selección de las herramientas RubyRuby
rest-open-uri
RubyfulSoup
WWW:Mechanize
Hpricot
http://hpricot.com/
Scanner impleme...
Selección de las herramientas RubyRuby
rest-open-uri
RubyfulSoup
WWW:Mechanize
Hpricot
Ofrece la misma funcionalidad que
H...
Rubyful Soup
Runtime: 4.71s
require 'rubygems'
require 'rubyful_soup'
require 'open-uri'
open("http://www.google.com/searc...
Selección de las herramientas RubyRuby
RubyfulSoup
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
H...
Selección de las herramientas RubyRuby
RubyfulSoup
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
H...
Selección de las herramientas RubyRuby
RubyfulSoup
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
H...
Selección de las herramientas RubyRuby
WWW:Mechanize
rest-open-uri
Hpricot
Ofrece la misma funcionalidad que
HTree + REXML...
Selección de las herramientas RubyRuby
rest-open-uri
WWW:Mechanize
Hpricot
Permite realizar interacciones
Rellenar y envia...
WWW::Mechanize
Runtime: 5.23s
require 'rubygems'
require 'mechanize'
agent = Mechanize.new
agent.set_proxy("localhost",808...
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",80...
Redirecciona por Javascript
Segundo intento: versión móvil
require 'rubygems'
require 'mechanize'
agent = Mechanize.new
agent.set_proxy("localhost",80...
Eureka!
require 'rubygems'
require 'mechanize'
class TuentiAPI
def initialize(login,password)
@login=login
@password=password
end
...
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[@...
Paso 3: Establecer el estado
Paso 3: Establecer el estado
class TuentiAPI
...
def actualizar_estado(msg)
form_actualizacion=inicio.forms.first
form_act...
Ninja Moves
Tor: navegando de forma
anónima
https://www.torproject.org/vidalia/
Red de encadenamiento de proxies
N peticiones salen de...
Gracias
CLOUD COMPUTING.
DESARROLLO DE APLICACIONESY
MINERÍA WEB
Programa de extensión universitariaUniversidad de Oviedo
Miguel F...
Screen scraping
Screen scraping
Upcoming SlideShare
Loading in …5
×

Screen scraping

2,809 views
2,723 views

Published on

Diapositivas correspondientes a la parte sobre recopilación de datos con screen scraping del curso de extensión universitaria "Cloud Computing. Desarrollo de Aplicaciones y Minería Web", celebrado en la Escuela Universitaria de Ingeniería Informática de Oviedo

Published in: Technology, Education
1 Comment
3 Likes
Statistics
Notes
No Downloads
Views
Total views
2,809
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide

Screen scraping

  1. 1. CLOUD COMPUTING. DESARROLLO DE APLICACIONESY MINERÍA WEB Programa de extensión universitariaUniversidad de Oviedo Miguel Fernández Fernández miguel@ThirdWay.es
  2. 2. Screen scraping
  3. 3. Porqué screen scraping La Web es fundamentalmente para humanos (HTML)
  4. 4. Porqué screen scraping La Web es fundamentalmente para humanos (HTML)
  5. 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. 6. Porqué screen scraping La Web es fundamentalmente para humanos (HTML)
  7. 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. 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. 9. Porqué screen scraping No siempre disponemos de una API
  10. 10. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano
  11. 11. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano Interpretar HTML
  12. 12. Porqué screen scraping No siempre disponemos de una API Necesitamos simular el comportamiento humano Interpretar HTML Realizar interacciones (Navegar)
  13. 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. 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. 15. Selección de las herramientas ¿Con qué lenguaje vamos a trabajar? Duck typing + Reflexión = Syntactic Sugar
  16. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 26. Selección de las herramientas RubyRuby rest-open-uri RubyfulSoup WWW:Mechanize Hpricot Ofrece la misma funcionalidad que HTree + REXML
  27. 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. 28. Selección de las herramientas RubyRuby RubyfulSoup WWW:Mechanize rest-open-uri Hpricot Ofrece la misma funcionalidad que HTree + REXML
  29. 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. 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. 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. 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. 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. 34. Manos a la obra
  35. 35. No tiene API pública >8000 usuarios nuevos cada día 2h de sesión promedio datos datos datos!
  36. 36. Novedades de tuenti
  37. 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)
  38. 38. Redirecciona por Javascript
  39. 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)
  40. 40. Eureka!
  41. 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. 42. Paso 2: Obtener las fotos
  43. 43. <div class=”box”> <div class=”box”> <div class=”box”>
  44. 44. 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
  45. 45. Paso 3: Establecer el estado
  46. 46. 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
  47. 47. Ninja Moves
  48. 48. 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
  49. 49. Gracias
  50. 50. CLOUD COMPUTING. DESARROLLO DE APLICACIONESY MINERÍA WEB Programa de extensión universitariaUniversidad de Oviedo Miguel Fernández Fernández miguel@ThirdWay.es

×