2009-02-08 6 views
1

Je souhaite extraire des liens de google.com; Mon code HTML ressemble à ceci:Comment extraire les liens du HTML en utilisant regex?

<a href="http://www.test.com/" class="l" 

Je m'a pris environ cinq minutes pour trouver une expression régulière qui fonctionne à l'aide www.rubular.com. Il est:

"(.*?)" class="l" 

Le code est:

require "open-uri" 
url = "http://www.google.com/search?q=ruby" 

source = open(url).read() 
links = source.scan(/"(.*?)" class="l"/) 

links.each { |link| puts #{link} 
} 

Le problème est, est-il pas sortir les liens de sites Web.

Répondre

0

Qu'est-ce qui ne va pas?

Vous essayez d'analyser HTML avec regex. Ne fais pas ça. Les expressions régulières ne peuvent pas couvrir la gamme de syntaxe permise même par XHTML valide, sans parler de la soupe de balises du monde réel. Utilisez une bibliothèque d'analyseurs HTML telle que Hpricot. FWIW, quand je récupère 'http://www.google.com/search?q=ruby' Je ne reçois 'class = "l"' nulle part dans le balisage retourné. Peut-être cela dépend de quel Google local vous utilisez et/ou si vous êtes connecté ou avez un cookie Google. (Votre script, comme moi, ne le ferait pas.)

+0

Eh bien, oui. Cela aussi. Les analyseurs HTML sont beaucoup mieux à ce sujet. –

4

Ces liens ont réellement class=l et non class="l". En passant, pour comprendre cela, j'ai ajouté un enregistrement à la méthode afin que vous puissiez voir la sortie à différentes étapes et le déboguer. J'ai cherché la chaîne que vous attendiez et je ne l'ai pas trouvée, c'est pourquoi votre regex a échoué. J'ai donc cherché la bonne corde que vous vouliez et j'ai changé l'expression rationnelle en conséquence. Les compétences de débogage sont pratiques.

require "open-uri" 
url = "http://www.google.com/search?q=ruby" 

source = open(url).read 

puts "--- PAGE SOURCE ---" 
puts source 

links = source.scan(/<a.+?href="(.+?)".+?class=l/) 

puts "--- FOUND THIS MANY LINKS ---" 
puts links.size 

puts "--- PRINTING LINKS ---" 
links.each do |link| 
    puts "- #{link}" 
end 

J'ai également amélioré votre regex. Vous recherchez un texte qui commence par l'ouverture d'un tag (<a), puis certains caractères dont vous n'avez pas besoin (.+?), un attribut href (href="), le contenu de l'attribut href que vous voulez pour capturer ((.+?)), certains espaces ou d'autres attributs (.+?), et enfin la classe attrubute (class=l). J'ai .+? à trois endroits là. le . signifie n'importe quel caractère, le + signifie qu'il doit y avoir une ou plusieurs des choses juste avant, et le ? signifie que le .+ devrait essayer de faire correspondre une chaîne aussi courte que possible.

2

Pour le dire franchement, le problème est que vous utilisez des regex. Le problème est que HTML est ce que l'on appelle un context-free language, tandis que les expressions régulières ne peuvent contenir que la classe de langages connue sous le nom regular languages. Ce que vous devez faire est d'envoyer les données de la page à un analyseur capable de gérer le code HTML, tel que Hpricot, puis de parcourir l'arborescence d'analyse obtenue à partir de l'analyseur.

Questions connexes