Nokogiri: встречаемся с ошибкой «неопределенный метод« text »для nil: NilClass» - PullRequest
5 голосов
/ 23 августа 2011

Я новичок в программировании, так что извините за новизну.Поэтому я использую Нокогири, чтобы очистить журнал полицейских преступлений.Вот код ниже:

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

Я использовал букмарклет гаджет-селектор, чтобы найти CSS-селектор для журнала (.brief).Когда я передаю «h3» через краткое.

Есть ли причина, по которой это происходит?Что мне не хватает?Спасибо!

Ответы [ 2 ]

8 голосов
/ 23 августа 2011

Чтобы уточнить, если вы посмотрите на структуру исходного кода HTML, вы увидите, что самое первое вхождение <div class="brief"> не имеет дочернего тега h3 (на самом деле он имеет только дочерний тег <p>).

Документы Нокогири говорят, что

at_css (* правила)

Поиск этого узла для первого появления правил CSS. Эквивалент css (rules) .first Для получения дополнительной информации см. Node # css.

Если вы позвоните по номеру at_css(*rules), в документе говорится, что это эквивалентно css(rules).first. Когда есть элементы (ваш класс .brief содержит h3), тогда возвращается объект Nokogiri::XML::Element, который отвечает на text, тогда как если ваш .brief не содержит h3, тогда объект NilClass возвращается, что, конечно, не отвечает на text

Поэтому, если мы вызываем css(rules) (не at_css, как у вас), мы получаем возвращенный объект Nokogiri::XML::NodeSet, для которого метод text() определен как (обратите внимание на alias)

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

, поскольку класс Enumerable, он перебирает своих детей, вызывающих их метод inner_text, и объединяет их всех вместе.

Поэтому вы можете выполнить проверку nil? или, если указано @floatless, просто используйте метод css

4 голосов
/ 23 августа 2011

Вам просто нужно заменить at_css на css, и все должно быть в порядке.

...