2016-06-24 11 views
0

Ich versuche, eine HTML-Seite mit Nokogiri zu analysieren, um einige Firmennamen zu erhalten.String-Elemente in einem Array richtig trennen

names = [] 
names << Nokogiri::HTML(mypage).css(".name a").text 

Mein Ergebnis ist:

["MikeGetsLeadsUruBlondeLaunch LIVERynoRyderBoyer ProductionsStrangerxCerealLume CubeKatapyMacaulay Outdoor PromotionsFlixit ABMedia MosaicLiftCast.TVcool.mediaPeekKLIKseeStreamingo SolutionsPvgnaalughaUser"] 

Aber was ich möchte ist bekommen:

["MikeGetsLeads", "Uru", "Blonde", "Launch LIVE", RynoRyderBoyer Productions", "Stranger", "xCereal", "Lume Cube", "Katapy", "Macaulay Outdoor Promotions", "Flixit AB", "Media Mosaic", "LiftCast.TV", "cool.media", "Peek", "KLIKsee", "Streamingo Solutions", "Pvgna", "alugha", "User"] 

Ich versuchte .split zu verwenden, aber es gefällt mir nicht das richtige Ergebnis geben weder . Auf dieser Seite gehört jeder Name zu einem <div>, so dass es in der HTML-Struktur klar getrennt ist.

Die HTML-Struktur sieht wie folgt aus

<div class='name'> 
<a href="https://angel.co/mikegetsleads-2" class="startup-link" data-id="1217822" data-type="Startup">MikeGetsLeads</a> 
</div> 
+0

Kann ich einen Blick werfen, wie sieht die HTML, die Sie analysieren möchten, aus? Kannst du es in deine Frage einfügen? – maicher

+0

Basierend auf dem Ergebnis Ihres Nokogiri-Snippets scheint es nicht möglich zu sein, das von Ihnen gewünschte Array zu generieren. Vielleicht sind weitere Details dazu hilfreich, wo Sie diese Daten erhalten. – Sinstein

+0

Danke für Ihre Kommentare! – Eric

Antwort

0

Das Problem ist, Sie verwenden text mit einem nodeset, nicht mit einzelnen Knoten. Bei einem NodeSet wird der gesamte Text zu einem einzelnen String verkettet. Per den NodeSet.inner_text AKA textdocumentation:

Holen Sie sich den inneren Text aller enthaltenen Knoten Objekte

und der eigentliche Code ist:

def inner_text 
    collect(&:inner_text).join('') 
end 

während Node.content AKA text oder inner_text

Gibt den Inhalt für diesen Knoten

Meditate dazu:

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<div> 
    <p>foo</p> 
    <p>bar</p> 
</div> 
EOT 

doc.css('p').class # => Nokogiri::XML::NodeSet 
doc.css('p').text # => "foobar" 

Stattdessen müssen Sie text auf einzelne Knoten verwenden:

doc.css('p').map{ |n| n.class } # => [Nokogiri::XML::Element, Nokogiri::XML::Element] 
doc.css('p').map{ |n| n.text } # => ["foo", "bar"] 

Die bisherige Linie vereinfacht werden kann :

doc.css('p').map(&:text) # => ["foo", "bar"] 

Siehe auch "How to avoid joining all text from Nodes when scraping".

+0

Danke, ich finde es jetzt! – Eric

0
require 'rubygems' 
require 'nokogiri' 
require 'pp' 

names = [] 
mypage = File.open("myhtml.html", "r") 
Nokogiri::HTML(mypage).css(".name a").each do |item| 
names << item.text 
end 

pp names 

kehrt:

["MikeGetsLeads", "MikeGetsLeads2", "MikeGetsLeads3"] 
+0

So toll, danke @rwaffen, es funktioniert auch! Es tut mir leid, ich lerne gerade Ruby, also bin ich irgendwie noob ... – Eric

+1

Vielleicht verwenden Sie 'names = Nokogiri :: HTML (meineSeite) .css (". Name a "). Map (&: text)' –

+0

@Eric Sie sollten sich nicht entschuldigen. Nokogiris Verhalten in dieser Situation (Aufruf von 'text' auf einem NodeSet-Objekt) ist ein wenig kontraintuitiv. –

Verwandte Themen