2010-12-03 38 views
0

Je voudrais faire une recherche dans une page Web si j'ai des résultats que j'ai besoin d'une propriété. Voici la page Web: link textHpricot rechercher comment

Je suis intéressé si, l'en-tête de la méta a la propriété avec la valeur « og: titre » ot ni, si a je veux le contenu valeur

Si nous regardez la source de la page, il a une potion de:

<meta 
property="og:title" content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" /> 

donc je veux un vrai résultat pour og: requête de titre et un Explorer le site de l'épave du Titanic par la valeur des médias sociaux [EXCLUSIF] pour la recherche suivante, comment le faire correctement

search("/html/head/meta[(@property='og:title']") ne retourne pas ce que je veux.

une suggestion?

+1

Je vous recommande de passer à [Nokogiri] (http://nokogiri.org). C'est facile à utiliser, comme Hpricot, mais d'après mon expérience, c'est beaucoup plus stable. –

+0

@ user529543: De la documentation de [this] (http://hpricot.com/demonstrations), il ne semble pas que Hpricot soit un moteur XPath standar plaintif ... –

Répondre

2

Utilisation:

/html/head/meta[@property='og:title']/@content 
+1

+1 pour la bonne réponse. Probablement, il vaut la peine de mentionner comment enregistrer les espaces de noms. –

+0

Vous pourriez vouloir vérifier cette réponse. Je n'ai rien quand j'utilise Hpricot: '>> (doc%"/html/head/meta [@ propriété = 'og: title']/@ content ") # => nil' et' >> (doc/"/html/head/meta [@ propriété = 'og: titre']/@ contenu ") # => # ' –

+0

@Greg: Ceci est une expression XPath correcte. La page est servie en tant que texte/html en plus de ressembler à un XHTML de transition (pas bien formé parce que certains ne s'échappent pas & & ...), donc je suppose qu'il y a une analyse spéciale qui me laisse errer sur la gestion des espaces de noms par @Dimitre –

1

Votre XPath a une erreur en elle, plus est trop restrictive:

search("/html/head/meta[(@property='og:title']") 

devrait être:

search("/html/head/meta[@property='og:title']") 

pour corriger l'erreur. Je le simplifierais à:

search("//meta[@property='og:title']") 

En outre, ce n'est pas très clair ce que vous voulez faire. Voulez-vous trouver

<meta 
    property="og:title" 
    content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" 
/> 

et extraire le paramètre content? Ou voulez-vous localiser le tag, confirmez qu'il contient à la fois le tag de propriété "og:title" et le contenu "Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]", puis effectuez un traitement ultérieur? Cela dit, il est souvent plus simple d'utiliser des accesseurs CSS au lieu de XPath. Je préfère utiliser Nokogiri, qui a deux sélecteurs XPath et CSS; J'utilise CSS ci-dessous:

require 'nokogiri' 
require 'open-uri' 

doc = Nokogiri::HTML(open('http://mashable.com/2010/08/06/expedition-titanic')) 
(doc % 'meta[property="og:title"]') 
=> #<Nokogiri::XML::Element:0x8084ee48 name="meta" attributes=[#<Nokogiri::XML::Attr:0x8084ed58 name="property" value="og:title">, #<Nokogiri::XML::Attr:0x8084ed1c name="content" value="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]">]> 

Nokogiri et hpricot soutenir la / et % un raccourci pour search et at respectivement. "Rechercher" renvoie un tableau de toutes les correspondances, et "at" renvoie uniquement la première correspondance. Ainsi, l'exemple ci-dessus obtient le premier noeud en utilisant le CSS, montrant que c'est la bonne piste. Je ne sais pas comment utiliser CSS pour correspondre à deux paramètres dans la même balise, donc je vais aller après tous<meta> tags avec property="og:title", puis filtre basé sur le paramètre content=:

(doc/'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] } 
=> [#<Nokogiri::XML::Element:0x8084ee48 name="meta" attributes=[#<Nokogiri::XML::Attr:0x8084ed58 name="property" value="og:title">, #<Nokogiri::XML::Attr:0x8084ed1c name="content" value="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]">]>] 

À ce moment-là nous avons le bon nœud dans le tableau retourné, ainsi vous pouvez extraire tout ce que vous voulez, ou plonger dans ses enfants et saccager et piller.Pour ce faire, vous aurez envie d'utiliser .first ou [0] pour obtenir au niveau du noeud réel pour un traitement ultérieur:

(doc/'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] }.first 

mise à jour basée sur la réponse de l'OP, en utilisant Nokogiri encore:

>> meta = (doc % 'meta[@property="og:title"]')['content'] 
>> meta #=> "Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" 
+0

Merci pour les réponses. –

1

Merci pour des réponses. Lorsque j'ai posté ma question je ne pouvais pas réaliser que j'ai une erreur dans la recherche. Il était vendredi soir ...

La recherche est correcte

elements = @doc.search("/html/head/meta[@property='og:title']") 
  • il est retiré un caractère ( d'expression avant @property

Cela donne le:

elements = <meta property="og:title" content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" /> 

résultat. Que je vérifie si j'ai quelque chose ou non, si je, que je dois la valeur du contenu

if elements.nil? 
    puts 'not found' 
    elsif elements.size > 0 
    puts "Found one, og:title = #{elements}" 
    content = elements.attr("content"); 
    puts content # this will display the content (it will be processed) 
    else 
    ... can come here the flow control? - theoretically yes, but in practice? 
    end 
+0

Au lieu d'ajouter vos mises à jour en tant que réponses, veuillez les ajouter à votre question initiale. Merci. –

+0

Oui, le flux ira à l'instruction 'else' si le' if' initial ou suivant 'elsif' ne correspondent pas à leur condition. Dans votre exemple 'elements' ne serait pas nul et serait vide. –