2011-11-25 13 views
7

En Perl no es un LWP module:¿Hay algún módulo como LWP de Perl para Ruby?

La colección libwww-perl es un conjunto de módulos de Perl que proporciona una interfaz de programación de aplicaciones simple y consistente (API) para el World-Wide Web. El objetivo principal de la biblioteca es proporcionar clases y funciones que le permitan escribir clientes WWW. La biblioteca también contiene módulos que son de uso más general e incluso clases que lo ayudan a implementar servidores HTTP simples.

¿Hay un módulo similar (gema) para Ruby?

actualización

Aquí es un ejemplo de una función que he hecho que extrae el URL de de un sitio web específico.

use LWP::UserAgent; 
use HTML::TreeBuilder 3; 
use HTML::TokeParser; 

sub get_gallery_urls { 
    my $url = shift; 

    my $ua = LWP::UserAgent->new; 
    $ua->agent("$0/0.1 " . $ua->agent); 
    $ua->agent("Mozilla/8.0"); 

    my $req = new HTTP::Request 'GET' => "$url"; 
    $req->header('Accept' => 'text/html'); 

    # send request 
    $response_u = $ua->request($req); 

    die "Error: ", $response_u->status_line unless $response_u->is_success; 

    my $root = HTML::TreeBuilder->new; 
    $root->parse($response_u->content); 

    my @gu = $root->find_by_attribute("id", "thumbnails"); 

    my %urls =(); 

    foreach my $g (@gu) { 
     my @as = $g->find_by_tag_name('a'); 

     foreach $a (@as) { 
      my $u = $a->attr("href"); 

      if ($u =~ /^\//) { 
       $urls{"http://example.com"."$u"} = 1; 
      } 
     } 
    } 

    return %urls; 
} 
+2

No estoy seguro de qué le hizo pensar 'LWP' es para analizar HTML. –

+0

Lo he usado para extraer todo tipo de cosas de HTML, y también completar formularios en línea, enviarlos y navegar en el sitio web con 'LWP'. –

+3

Wow, eso hubiera sido mucho más simple usando WWW :: Mechanize en Perl (o Ruby). –

Respuesta

10

La coincidencia más cercana es probablemente httpclient, que pretende ser el equivalente de LWP. Sin embargo, dependiendo de lo que planeas hacer, puede haber mejores opciones. Si planea seguir enlaces, completar formularios, etc. para raspar contenido web, puede usar Mechanize que es similar al módulo perl con el mismo nombre. También hay más gemas específicas de Ruby, como la excelente Rest-client y HTTParty (mi favorita). Vea el HTTP Clients category of Ruby Toolbox para una lista más grande.

actualización: Aquí está un ejemplo de cómo encontrar todos los enlaces en una página en Mechanize (Ruby, pero sería similar en Perl):

require 'rubygems' 
require 'mechanize' 

agent = Mechanize.new 

page = agent.get('http://example.com/') 

page.links.each do |link| 
    puts link.text 
end 

P. S. Como ex-Perler yo solía preocuparme por abandonar el excelente CPAN, ¿me pintaría en una esquina con Ruby? ¿No podría encontrar un equivalente a un módulo en el que confío? Esto resultó no ser un problema en absoluto, y de hecho últimamente ha sido todo lo contrario: Ruby (junto con Python) tiende a ser el primero en obtener soporte para clientes para nuevas plataformas/servicios web, etc.

+0

Esa es exactamente la situación en la que me encuentro. Conozco a Perl, y conozco algunos libros de Perl de memoria. He escrito un sitio web Web 2.0 en Perl, pero no fue divertido y demasiado difícil. Entonces mi plan es resolver problemas futuros en Ruby, y solo tengo que aceptar que al principio tomará 20 veces más. –

+2

¿Por qué no aprender un marco decente y apilar como Mojolicious sobre Plack/PSGI? Desarrollo rápido, moderno, elegante, portátil ... una gran opción que se basa en su destreza de Perl existente. – DavidO

+0

@DavidO Al leer acerca de Plack, no tengo claro qué es exactamente lo que simplifica. ¿Conoces un ejemplo de antes/después? –

3

Así es como se vería tu función en ruby.

require 'rubygems' 
require "mechanize" 

def get_gallery_urls url 
    ua = Mechanize.new 
    ua.user_agent = "Mozilla/8.0" 
    urls = {} 

    doc = ua.get url 
    doc.search("#thumbnails a").each do |a| 
     u = a["href"] 
     urls["http://example.com#{u}"] = 1 if u =~ /^\// 
    end 

    urls 
end 

Mucho mejor :)

+0

¡Eso es increíble! –

+0

¿No tiene que verificar los valores devueltos? En mi caso, necesito comprobar '$ response_u-> is_success' para asegurarme de que la página se descargó correctamente antes de analizarla. –

+1

Se generará una excepción si algo sale mal. Puede manejarlo en la función si lo desea o ignorarlo con algo como: gallery_urls = get_gallery_urls (myurl) rescue nil – pguardiario

3

que utilizan Perl durante años y años, y le gusta LWP. Fue una gran herramienta. Sin embargo, aquí es cómo iría sobre la extracción de URL de una página.Este no es un sitio de rastreo, pero eso sería una cosa fácil:

require 'open-uri' 
require 'uri' 

urls = URI.extract(open('http://example.com').read) 
puts urls 

Con la salida resultante que parece:

 
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 
http://www.w3.org/1999/xhtml 
http://www.icann.org/ 
mailto:[email protected]?subject=General%20website%20feedback 

escrito que como método:

require 'open-uri' 
require 'uri' 

def get_gallery_urls(url) 
    URI.extract(open(url).read) 
end 

o, más cerca de la función original mientras lo hace Ruby-way:

def get_gallery_urls(url) 
    URI.extract(open(url).read).map{ |u| 
    URI.parse(u).host ? u : URI.join(url, u).to_s 
    } 
end 

o, siguiendo más de cerca al código original:

require 'nokogiri' 
require 'open-uri' 
require 'uri' 

def get_gallery_urls(url) 
    Nokogiri::HTML(
    open(url) 
) 
    .at('#thumbnails') 
    .search('a') 
    .map{ |link| 
     href = link['href'] 
     URI.parse(link[href]).host \ 
     ? href \ 
     : URI.join(url, href).to_s 
    } 
end 

Una de las cosas que me atrajo a Ruby es su capacidad para ser legible, sin dejar de ser conciso.

Si desea desplegar sus propias funciones basadas en TCP/IP, la biblioteca de red estándar de Ruby es el punto de partida. Por defecto se obtiene:

 
net/ftp 
net/http 
net/imap 
net/pop 
net/smtp 
net/telnet 

con el basado en SSL ssh, scp, sftp y otros disponibles como gemas. Use gem search net -r | grep ^net- para ver una lista corta.

1

Esto es más de una respuesta para cualquiera que mire esta pregunta y necesite saber cuáles son las alternativas más fáciles/mejores/diferentes al raspado web general con Perl en comparación con el uso de LWP (e incluso WWW::Mechanize).

He aquí una selección rápida de los módulos de raspado web en CPAN:

NB. Arriba está solo en orden alfabético, así que elija su veneno favorito :)

Durante la mayor parte de mi raspado web reciente he estado usando pQuery. Puede ver que hay bastantes examples of usage on SO.

A continuación se muestra el ejemplo usando get_gallery_urlspQuery:

use strict; 
use warnings; 
use pQuery; 

sub get_gallery_urls { 
    my $url = shift; 
    my %urls; 

    pQuery($url) 
     ->find("#thumbnails a") 
     ->each(sub { 
      my $u = $_->getAttribute('href'); 
      $urls{'http://example.com' . $u} = 1 if $u =~ /^\//; 
     }); 

    return %urls; 
} 

PS. Como dijo Daxim en los comentarios, hay muchas herramientas Perl excelentes para raspar web. ¡La parte más difícil es simplemente elegir cuál usar!

Cuestiones relacionadas