html perl parsing url cpan

¿Cómo puedo extraer URL y vincular texto desde HTML en Perl?



parsing cpan (11)

Consulte el uso del módulo WWW :: Mechanize para esto. Le buscará sus páginas web y luego le proporcionará fácil de trabajar con listas de URL.

my $mech = WWW::Mechanize->new(); $mech->get( $some_url ); my @links = $mech->links(); for my $link ( @links ) { printf "%s, %s/n", $link->text, $link->url; }

Muy simple, y si buscas navegar a otras URL en esa página, es aún más simple.

Mech es básicamente un navegador en un objeto.

Previamente le pregunté cómo hacer esto en Groovy. Sin embargo, ahora estoy reescribiendo mi aplicación en Perl debido a todas las bibliotecas de CPAN.

Si la página contenía estos enlaces:

<a href="http://www.google.com">Google</a> <a href="http://www.apple.com">Apple</a>

La salida sería:

Google, http://www.google.com Apple, http://www.apple.com

¿Cuál es la mejor manera de hacer esto en Perl?


HTML es un lenguaje de marcado estructurado que debe analizarse para extraer su significado sin errores. El módulo Sherm enumerado analizará el HTML y extraerá los enlaces por usted. Las soluciones ad hoc basadas en expresiones regulares pueden ser aceptables si usted sabe que sus entradas siempre se formarán de la misma manera (no olvide los atributos), pero un analizador es casi siempre la respuesta correcta para procesar texto estructurado.


O considere mejorar HTML :: LinkExtor para hacer lo que quiera y enviar los cambios al autor.


Otra forma de hacerlo es usar XPath para consultar HTML analizado. Es necesario en casos complejos, como extraer todos los enlaces en div con clase específica. Utilice HTML :: TreeBuilder :: XPath para esto.

my $tree=HTML::TreeBuilder::XPath->new_from_content($c); my $nodes=$tree->findnodes(q{//map[@name=''map1'']/area}); while (my $node=$nodes->shift) { my $t=$node->attr(''title''); }


Las respuestas anteriores fueron perfectamente buenas y sé que llegué tarde a la fiesta, pero esto se superó en el feed de [perl] así que ...

XML :: LibXML es excelente para el análisis de HTML e inmejorable para la velocidad. Establezca la opción de recover al analizar HTML mal formado.

use XML::LibXML; my $doc = XML::LibXML->load_html(IO => /*DATA); for my $anchor ( $doc->findnodes("//a[/@href]") ) { printf "%15s -> %s/n", $anchor->textContent, $anchor->getAttribute("href"); } __DATA__ <html><head><title/></head><body> <a href="http://www.google.com">Google</a> <a href="http://www.apple.com">Apple</a> </body></html>

-caracteriza-

Google -> http://www.google.com Apple -> http://www.apple.com


Si eres aventurero y quieres probar sin módulos, algo así debería funcionar (adaptarlo a tus necesidades):

#!/usr/bin/perl if($#ARGV < 0) { print "$0: Need URL argument./n"; exit 1; } my @content = split(//n/,`wget -qO- $ARGV[0]`); my @links = grep(/<a.*href=.*>/,@content); foreach my $c (@links){ $c =~ /<a.*href="([/s/S]+?)".*>/; $link = $1; $c =~ /<a.*href.*>([/s/S]+?)<//a>/; $title = $1; print "$title, $link/n"; }

Es probable que haya algunas cosas que hice mal aquí, pero funciona en un puñado de casos de prueba que intenté después de escribirlo (no cuenta para cosas como <img> etiquetas, etc.).


Podemos usar expresiones regulares para extraer el enlace con su texto de enlace. Esta es también la única forma.

local $/ = ''''; my $a = <DATA>; while( $a =~ m/<a[^>]*?href=/"([^>]*?)/"[^>]*?>/s*([/w/W]*?)/s*<//a>/igs ) { print "Link:$1 /t Text: $2/n"; } __DATA__ <a href="http://www.google.com">Google</a> <a href="http://www.apple.com">Apple</a>



HTML :: LinkExtractor es mejor que HTML :: LinkExtor

Puede proporcionar texto de enlace y URL.

Uso:

use HTML::LinkExtractor; my $input = q{If <a href="http://apple.com/"> Apple </a>}; #HTML string my $LX = new HTML::LinkExtractor(undef,undef,1); $LX->parse(/$input); for my $Link( @{ $LX->links } ) { if( $$Link{_TEXT}=~ m/Apple/ ) { print "/n LinkText $$Link{_TEXT} URL $$Link{href}/n"; } }


Me gusta usar pQuery para cosas como esta ...

use pQuery; pQuery( ''http://www.perlbuzz.com'' )->find( ''a'' )->each( sub { say $_->innerHTML . q{, } . $_->getAttribute( ''href'' ); } );

También consulte esta pregunta previa de .com Emulación de la funcionalidad lex like en Perl o Python para obtener respuestas similares.


Sherm recomendó HTML :: LinkExtor , que es casi lo que quieres. Lamentablemente, no puede devolver el texto dentro de la etiqueta <a>.

Andy recomendó WWW :: Mecanizar . Esa es probablemente la mejor solución.

Si encuentra que WWW :: Mechanize no es de su agrado, intente HTML :: TreeBuilder . Construirá un árbol similar al DOM a partir del HTML, que luego podrá buscar los enlaces que desee y extraer cualquier contenido cercano que desee.