Несмотря на то, что вы заявили, что ваш код снова работает, позвольте мне указать на некоторые недостатки в вашем коде:
Вы просите Nokogiri разобрать канал RSS RSS как HTML.Вместо этого вы должны использовать Nokogiri::XML( ... )
;Ничего страшного, и не причина этой проблемы.
Вы используете return
внутри каждого из них.В показанном вами коде это обычно вызывает LocalJumpError: unexpected return
.Очевидно, что вы используете этот код внутри метода (который вы нам не показали).Использование return
внутри блока не приводит к выходу из блока, а скорее вызывает возврат метода вложения.Что касается того, что вы, вероятно, хотите вместо этого, читайте дальше:
Вы создаете локальную переменную url
, но не используете ее.
Я предполагаю, что вы пытались найти только url
из каждого канала.Однако, используя XPath //[@href]
, вы действительно находили каждый элемент в документе, который имеет атрибут href="..."
.Вы повторно находите этот полный набор элементов для каждого entry
в документе.(За исключением того, что из-за оператора return
вы выходили раньше.) А затем, запросив text
элемента, вы бы ничего не получили.
Что касается фактической ошибки, которую вы получили, вы пытались получить доступ к podcast.url
, но элементы Nokogiri не имеют метода url
.
Учитывая схему каналов изURL, который вы указали, вот несколько способов получить массив атрибута href="..."
каждого entry/link
в документе в порядке возрастания простоты и предпочтения:
Почти прямой перевод
urls = []
itunes_top_300.search('//entry').each do |podcast|
# Find the first element below the current one that has an href attribute
# and then get the value of that attribute
url = podcast.at_xpath(".//[@href]")['href']
# Add this url to the array
urls << url
end
# As the last statement in your method, return urls (without word 'return')
urls
Избавление от локальной переменной
urls = []
itunes_top_300.search('//entry').each do |podcast|
# It's pretty clear what we're doing, so no need to name the value
# before we add it to the array
urls << podcast.at_xpath(".//[@href]")['href']
end
urls
Очистка с помощью Map
# Run through the array and convert each element to the return value
# of the block
itunes_top_300.search('//entry').map do |podcast|
podcast.at_xpath(".//[@href]")['href']
end
# If the above is the last statement of the method, the method will return the
# result of the map as the return value of the method
Запрос только атрибута напрямую
itunes_top_300.search('//entry').map do |podcast|
# Instead of getting the element, get the attribute itself
# Use `to_s` or `value` to get the text of the attribute node.
podcast.at_xpath(".//[@href]/@href").to_s
end
Использование только XPath, чтобы получить то, что мы хотели в первую очередь
# Take an array of attribute nodes and get their values
itunes_top_300.xpath('//entry/link/@href').map{ |attr| attr.to_s }
Использование синтаксиса Ruby 1.9 для сокращения вызова карты
# Map the result of the XPath by calling `to_s` on each
itunes_top_300.xpath('//entry/link/@href').map( &:to_s )