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

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:

  Google 

  Apple 

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?

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.

Eche un vistazo a HTML :: LinkExtractor y HTML :: LinkExtor , parte del paquete HTML :: Parser .

HTML :: LinkExtractor es similar a HTML :: LinkExtor, excepto que además de obtener la URL, también obtiene el texto de enlace.

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(//,@content); foreach my $c (@links){ $c =~ //; $link = $1; $c =~ /([\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 tags, etc.).

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 stackoverflow.com Emulación de la funcionalidad lex like en Perl o Python para obtener respuestas similares.

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'); } 

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

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.

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

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__  Google Apple  

-Caracteriza-

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

HTML :: LinkExtractor es mejor que HTML :: LinkExtor

Puede proporcionar texto de enlace y URL.

Uso:

  use HTML::LinkExtractor; my $input = q{If  Apple }; #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"; } } 

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.

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

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