2010-12-03 14 views
0

Ich würde gerne eine Suche in einer Webseite tun, wenn ich Ergebnis habe, als ich eine Eigenschaft brauche. Hier ist die Webseite: link textHpricot Suche wie

ich, wenn interessiert bin, die Meta der Header hat die Eigenschaft mit dem Wert „og: title“ ot noch, wenn habe ich den Inhalt Wert

Wenn wir wollen, Blick auf die Quelle der Seite, die ihm einen Trank hat:

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

so möchte ich ein wahres Ergebnis für og: title Abfrage und Entdecken sie die Titanic Wrack über Social Media [EXCLUSIVE] Wert für die nächste Suche, wie man es richtig macht

search("/html/head/meta[(@property='og:title']") gibt nicht zurück, was ich will.

irgendein Vorschlag?

+1

benötigen würde ich empfehlen, auf Schalt [Nokogiri] (http://nokogiri.org). Es ist einfach zu bedienen, wie Hpricot, aber meiner Erfahrung nach ist es viel stabiler. –

+0

@ user529543: Von [dieser] (http://hpricot.com/demonstrations) Dokumentation sieht es nicht wie Hpricot ist eine Standard-XPath-Engine beschweren ... –

Antwort

2

Verwendung:

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

+1 für die richtige Antwort. Wahrscheinlich ist es erwähnenswert, wie man Namespaces registriert. –

+0

Könnte diese Antwort überprüfen. Ich bekomme nichts wenn ich Hpricot benutze: '>> (doc%"/html/head/meta [@ property = 'og: title']/@ content ") # => nil' und' >> (doc/"/html/head/meta [@ Eigenschaft = 'og: title']/@ content ") # => # ' –

+0

@Greg: Dies ist ein korrekter XPath-Ausdruck. Die Seite wird als text/html geliefert, abgesehen davon, dass sie wie ein Übergangs-XHTML aussieht (nicht gut formatiert, weil einige nicht "&" ...), also nehme ich an, dass es spezielle Parsing-Prozeduren gibt, die mich auf die Namespace-Behandlung hinweisen von @Dimitre –

1

Ihre XPath hat darin einen Fehler, und ist zu restriktiv:

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

sollte sein:

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

den Fehler zu beheben. Ich würde es zu vereinfachen:

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

Auch ist es nicht ganz klar, was Sie tun möchten. Wollen Sie

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

finden und den Parameter content extrahieren? Oder möchten Sie das Tag lokalisieren, bestätigen, dass es sowohl das "og:title" Property-Tag als auch den "Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" Inhalt enthält, und dann weiterverarbeiten?

Das heißt, oft ist es einfacher, CSS-Accessoren anstelle von XPath zu verwenden. Ich bevorzuge Nokogiri, das sowohl XPath- als auch CSS-Selektoren hat; Ich bin mit CSS unter:

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 und Hpricot die / und % Abkürzung für search und at bzw. unterstützen. "Suche" gibt ein Array aller Übereinstimmungen zurück und "at" gibt nur die erste Übereinstimmung zurück. Das obige Beispiel ruft den ersten Knoten mit dem CSS ab und zeigt, dass dies der richtige Track ist. Ich bin mir nicht sicher, wie CSS zu verwenden, um zwei Parameter im gleichen Tag passen, ich werde so gehen nach alle<meta> Tags mit property="og:title", dann auf dem content= Parameter basierend Filter:

(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]">]>] 

An diesem Punkt Wir haben den richtigen Knoten im zurückgegebenen Array, so dass du alles extrahieren kannst, was du willst, oder in seine Kinder eintauchen und plündern und plündern kannst.Um dies zu tun Sie werden .first oder [0] verwenden, bei dem aktuellen Knoten für die Weiterverarbeitung zu erhalten:

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

aktualisiert basierend auf OP Antwort, mit Nokogiri noch:

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

Danke für die Antworten. –

1

Dank für Antworten. Als ich meine Frage gepostet habe, konnte ich nicht erkennen, dass ich einen Fehler bei der Suche habe. Es war Freitag Abend ...

Die richtige Suche ist

elements = @doc.search("/html/head/meta[@property='og:title']") 
  • es entfernt wird ein ( Charakter aus der Expression vor @property

Dies gibt ihm den:

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

Ergebnis. als ich überprüft habe, ob ich etwas haben oder nicht, wenn ich, als ich den Inhalt Wert

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

Anstatt Ihre Aktualisierungen als Antworten hinzuzufügen, fügen Sie sie bitte zu Ihrer ursprünglichen Frage hinzu. Vielen Dank. –

+0

Ja, der Fluss wird zur "else" -Anweisung wechseln, wenn das ursprüngliche "if" oder das folgende "elsif" nicht mit ihrer Bedingung übereinstimmt. In Ihrem Beispiel wären "Elemente" nicht null und wären leer. –