2011-08-22 12 views
5

Sono un novizio per programmatore quindi scusate la mia novicità. Quindi sto usando Nokogiri per raschiare un registro dei criminali della polizia. Ecco il codice qui sotto:Nokogiri: errore "metodo non definito 'testo' per nil: NilClass"

require 'rubygems' 
require 'nokogiri' 
require 'open-uri' 

url = "http://www.sfsu.edu/~upd/crimelog/index.html" 
doc = Nokogiri::HTML(open(url)) 
puts doc.at_css("title").text 
doc.css(".brief").each do |brief| 
puts brief.at_css("h3").text 
end 

ho usato il bookmarklet selettore di gadget per trovare il selettore CSS per il registro (.brief). Quando passo "h3" a brief.at_css ottengo tutti i tag h3 con il contenuto all'interno.

Tuttavia, se aggiungo il metodo .text per rimuovere i tag, ottengo l'errore NoMethod.

C'è qualche motivo per cui questo sta accadendo? Cosa mi manca? Grazie!

risposta

8

Per chiarire se si guarda alla struttura del codice HTML si vedrà che la prima occorrenza di <div class="brief"> non ha un tag bambino h3 (in realtà ha solo un tag bambino <p>).

Il Nokogiri Docs dicono che

at_css (* regole)

Cerca nel nodo per la prima occorrenza di regole CSS. Equivale a css (rules) .first Vedi Node # css per ulteriori informazioni.

Se si chiama at_css(*rules), la documentazione indica che è equivalente a css(rules).first. Quando ci sono oggetti (la classe .brief contiene un h3) poi un oggetto Nokogiri::XML::Element viene restituito che risponde ad text, mentre se il vostro .brief non contiene un h3 poi un oggetto NilClass viene restituito, che ovviamente non risponde a text

Quindi, se chiamiamo css(rules) (non at_css come si deve) otteniamo un oggetto Nokogiri::XML::NodeSet restituito, che ha il metodo text() definito come (notare il alias)

# Get the inner text of all contained Node objects 
    def inner_text 
    collect{|j| j.inner_text}.join('') 
    end 
    alias :text :inner_text 

perché la classe è Enumerable itera sui suoi figli che chiamano il loro metodo inner_text e li unisce tutti insieme.

Pertanto è possibile eseguire un controllo nil? o come @floatless dichiarato correttamente basta usare il metodo

+0

Incredibile che l'abbia fatto! Grazie mille! – aboutaaron

4

Hai solo bisogno di sostituire at_css con css e tutto dovrebbe essere a posto.

+0

css Solo che 'css' restituisce una serie di nodi, dove' at_css' restituisce un nodo, in modo che il serie di nodi dovrà essere ripetuto. –

+0

Tranne che è possibile chiamare #inner_text su un NodeSet. Se farà ciò che vuoi dipende da ciò che vuoi che accada quando ci sono> 1 partite. Se ci sono sempre solo 0 o 1, probabilmente farà quello che vuoi. – jrochkind

Problemi correlati