12
votes

Obtenir tous les liens d'une page Web utilisant Ruby

J'essaie de récupérer chaque lien externe d'une page Web utilisant Ruby. J'utilise string.scan code> avec cette regex: xxx pré>

alors, je peux utiliser gsub pour supprimer la partie HREF: p>

str.gsub(/href=['"]/)


5 commentaires

N'essayez pas d'analyser HTML avec des expressions régulières, un analyseur HTML vous servira mieux.


Étant donné que l'analyse HTML est plus compliquée que vous le pensez probablement et il y a beaucoup de HTML cassés là-bas, que de simples expressions régulières ne manipulent pas: Stackoverflow.com/questions/4231382/...


En fait, dans ce cas simple, je m'attendrais à ce que la solution de regex soit plus robuste que la solution analysante. Je remplacerais [^ "] par [^">] cependant. Je m'attendrais également à ce que ce soit un peu plus rapide. Mais cela dépend un peu sur le but. Si cela se déroule dans un système de production qui doit travailler pendant des années, j'irais un analyseur, s'il s'agit d'un script de propre usage, définitivement regex.


Dans tous les cas, je m'attendrais à une simple solution d'analyse plus robuste qu'une solution de regex simple. :)


@Markijbema, des problèmes non artificiels que nous voyons souvent dans HTML serait un espace sur le = ou manquant des citations simples, ou l'utilisation de citations double. Même dans un seul document d'un créateur, ces choses se produisent souvent. Une plus grande réégalité complexe peut être écrite pour gérer cela, mais un analyseur le fera sans problème.


5 Réponses :


1
votes

Pouvez-vous mettre des groupes dans votre regex? Cela réduirait vos expressions régulières à 1 au lieu de 2.


0 commentaires

17
votes

Utiliser des expressions régulières convient à un script rapide et sale, mais Nokogiri est très simple à utiliser: xxx

Si vous voulez juste la méthode, le refacteur un peu à vos besoins: xxx


2 commentaires

Pouvez-vous m'expliquer les avantages? Le code semble plus compliqué qu'avec Regex et Scan. Je suis aussi curieux de savoir quelle solution est plus rapide.


@tokland, je pense que tu veux Nokogiri :: html. Notez également l'obligation d'extraire uniquement des liens absolus.



4
votes

Pourquoi vous n'utilisez pas de groupes dans votre modèle? E.G.

/http[s]?:\/\/(.+)/i


0 commentaires

6
votes

Mécaniser utilise Nokogiri sous la hotte mais a des Nexéties intégrées pour analyse HTML, y compris les liens:

require 'mechanize'

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

page.links_with(:href => /^https?/).each do |link|
  puts link.href
end


3 commentaires

Je conviens que lorsque vous devez analyser HTML, vous ne voulez pas utiliser les regextes. Mais dans ce cas, je pense qu'une regex suffirait, car vous n'avez pas eu de problème avec la non régularité de HTML (car il n'y a pas de récursivité impliquée). Pourriez-vous penser à un exemple (non artificiel) où cette regex (avec mon amélioration mentionnée dans mon commentaire sur la question) échouerait?


J'aime bien votre solution BTW, c'est court et lisible, mais je n'aime pas vraiment faire des vérités extrêmement absolues, comme "tu ne toucheras pas HTML avec des regexes".


@markijbema j'ai ajouté un peu à expliquer. Voici un cas que j'ai vu: foo . Il y a aussi parfois des lignes neuves là-bas.



6
votes

Je suis un grand fan de Nokogiri, mais pourquoi réinventer la roue?

Ruby's URI Module a déjà l'extrait méthode pour le faire: xxx

de la DOCS:

extrait les URI d'une chaîne. Si le bloc donné, iTère à travers toutes les URI apparuées. Retourne nil si le bloc est donné ou une matrice avec des allumettes. xxx

Vous pouvez utiliser Nokogiri pour marcher sur le DOM et tirer toutes les balises contenant des URL ou la récupération du texte et le transmettre à uri.extract < / Code>, ou simplement laisser uri.extract faire tout le tout.

et, pourquoi utiliser un analyseur, tel que Nokogiri, au lieu de modèles de regex? Étant donné que HTML, et XML, peuvent être formatés de différentes manières et rendant toujours correctement sur la page ou transférer efficacement les données. Les navigateurs sont très indulgent quand il s'agit d'accepter une mauvaise balise. Les modèles de regex, quant à eux, travaillent dans des gammes très limitées d'une "acceptabilité", où cette gamme est définie par la manière dont vous anticipez les variations du balisage ou, à l'inverse, dans quelle mesure vous anticipez les moyens de votre motif. Présenté avec des modèles inattendus.

Un analyseur ne fonctionne pas comme une regex. Il construit une représentation interne du document, puis traverse cela. Il se fiche de la manière dont le fichier / marquage est défini, ses travaux sur la représentation interne de la DOM. Nokogiri détend sa analyse pour gérer HTML, car le HTML est notorieux d'être mal écrit. Cela nous aide parce que la plupart des Nokogiri HTML non validant peuvent le réparer. De temps en temps, je rencontrerai quelque chose qui est si mal écrit que Nokogiri ne peut pas le réparer correctement, alors je vais devoir lui donner un coup de pouce mineur en modifiant le HTML avant de le transmettre à Nokogiri; Je vais toujours utiliser l'analyseur, plutôt que d'essayer d'utiliser des motifs.


0 commentaires