2011-01-24 5 views
1

следующий код:рубин каждый цикл не отделки для каждого элемента

# fetch the top 300 podcasts from itunes 
itunes_top_300 = Nokogiri.HTML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=25/xml")) 

# parse the returned xml with nokogiri 
itunes_top_300.xpath('//feed/entry').each do |entry| 
    name = entry.xpath("//name").text 
    url = entry.xpath("//link/@href").text 
    category = entry.xpath("//category/@term").text 
    hosts = entry.xpath("//artist").text 
    summary = entry.xpath("//summary").text 
    artwork = entry.xpath("//image[@height='170']").text 
    return name + url 
end 

выводит в окне:

Itunes StoreThis Американский LifeNPR: Подождите, подождите ... Не Говори Меня! PodcastStuff, который вы должны знать, Freakonomics RadioNPR: свежий воздух PodcastNPR: автомобильный разговор PodcastWNYC's RadiolabDespicable MePearls перед анимированными мультфильмами SwineApp.comMot: новости о префектуре Прейри из озера ВобегонХарри Поттер 1-5 лет подкаста на вечеринках в домах - техасцы Featurette: Выполнение Heist - создание TakersNPR: Planet Money PodcastStuff, который вы пропустили в истории ClassThe Dave Ramsey ShowBook ​​ReviewГлобальные новостиВампиры Suck ClipsNPR: Наука Пятница PodcastДругие ребята Crash и BurnBack для работыNPR: все песни считаются PodcastNPR: Tiny Desk Concerts Podcasthttp: //itunes.apple.com/WebObjects/MZStore. woa/wa/viewTop? id = 38 & popId = 3http: //ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/toppodcasts/limit=25/xml? cc = ushttp: // itunes. apple.com/us/podcast/this-american-life/id201671138?uo=2 & uo = 2http: //itunes.apple.com/us/podcast/npr-wait-wait-dont-tell-me/id121493804? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/stuff-you-should-know/id278981407? Uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/freakonomics-radio/id354668519? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/npr-fresh-air-podcast/id214089682? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/npr-car-talk-podcast/id253191823? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/wnycs-radiolab/id152249110? uo = 2 & uo = 2http: // itunes .apple.com/us/podcast/despicable-me/id399247154? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/pearls-before-swine-animated/id409382502? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/the-moth-podcast/id275699983? Uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/apm-a-prairie-home -companions/id215352157? uo = 2 & uo = 2 http://itunes.apple.com/us/podcast/harry-potter-years-1-5-podcast/id322144752?uo=2 & uo = 2http: //itunes.apple.com/us/podcast/ace- on-the-house/id414294132? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/takers-takers-featurette-executing/id412910974? uo = 2 & uo = 2http: // itunes. apple.com/us/podcast/npr-planet-money-podcast/id290783428?uo=2 & uo = 2http: //itunes.apple.com/us/podcast/stuff-you-missed-in-history/id283605519? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/the-dave-ramsey-show/id77001367? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/ book-review/id120315179? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/global-news/id135067274? uo = 2 & uo = 2http: //itunes.apple.com/us/ podcast/vampires-suck-clips/id405404825? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/npr-science-friday-podcast/id73329284? Uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/other-guys-crash- и-burn/id407622041? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/back-to-work/id415535037? uo = 2 & uo = 2http: //itunes.apple.com/ us/podcast/npr-all-songs-thought-podcast/id79687345? uo = 2 & uo = 2http: //itunes.apple.com/us/podcast/npr-tiny-desk-concerts-podcast/id362115318? uo = 2 & uo = 2

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

Спасибо.

+0

Что вы хотите, чтобы сделать это для каждого? – Phrogz

+1

@Phrogz: Я предполагаю, что он хочет напечатать что-то вроде «{name} {url} {name} {url}", а не "{name} {name} ... {name} {url} {url} .. . {url} " –

+0

@ Анон - да, это именно оно. – lightyrs

ответ

2

Есть несколько вещей, которые вызывают эту проблему. Во-первых, когда вы используете возврат внутри каждого цикла, вы фактически разбиваете его, поэтому он повторяется только один раз, а не 25 раз.

Во-вторых, вы можете не заметить, что он запускается только один раз, потому что, когда вы используете // имя в xpath, он возвращает все имена.

Может быть, вы могли бы сделать что-нибудь подобное вместо:

# Returns top 25 since the url includes limit=25 
itunes_top_25 = Nokogiri.XML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=25/xml")) 

names_and_urls = itunes_top_25.xpath('//feed/entry').map do |entry| 
    name = entry.xpath("./name").text 
    url = entry.xpath("./link/@href").text 
    category = entry.xpath("./category/@term").text 
    hosts = entry.xpath("./artist").text 
    summary = entry.xpath("./summary").text 
    artwork = entry.xpath("./image[@height='170']").text 
    [name, url] 
end  

Я изменил // имя ./name так, что он возвращает только для текущего узла. Я также изменил каждый на карту так, чтобы назначить переменную массиву со всеми значениями, возвращаемыми блоком. И я удалил звонок, чтобы вернуться, поскольку он не нужен.

Таким образом, это приведет к массиву массивов, содержащих имена и URL-адреса.

+0

Большое вам спасибо. Это прекрасно, и ваше объяснение было очень образованным. – lightyrs

+0

Вы можете изменить принятый ответ, чтобы показать разбор XML как XML вместо HTML. – Phrogz

+0

Конечно, пропустил этот. Спасибо, что указали это. – DanneManne

0

Вы объявляете переменные с нужным вам материалом, а затем выбрасываете его, потому что вы только return name + url.

вместо этого попытаться return name + url + category + thing1 + thing2

еще лучше

return [url,category,thing1,thing2]

+0

Правда, но не имеет отношения к заданному вопросу. –

+0

Перед редактированием было очень неясно, о чем спрашивали. – EnabrenTane

1

return Позвонив вы останавливаете свой each петлю на первой итерации. Наверное, ты этого не хотел. Кроме того, используя xpath //name внутри вашего цикла, вы начинаете в верхней части документа и находите каждый элемент имени во всем документе. Следовательно, когда вы находите первый <entry>, вы затем возвращаете массив, образованный путем объединения массива каждого элемента <name> в документе с массивом каждого элемента <url> в документе.

Вы, вероятно, хотите или этот:

require 'nokogiri' 
require 'open-uri' 
# fetch the top 300 podcasts from itunes 
# Use XML instead of HTML 
itunes_top_300 = Nokogiri::XML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=25/xml")) 
itunes_top_300.remove_namespaces! 

itunes_top_300.xpath('//entry').each do |entry| 
    name = entry.xpath("name").text 
    url = entry.xpath("link/@href").text 
    puts "#{name}: #{url}" 
end 
#=> This American Life: http://itunes.apple.com/us/podcast/this-american-life/id201671138?uo=2&uo=2 
#=> NPR: Wait Wait... Don't Tell Me! Podcast: http://itunes.apple.com/us/podcast/npr-wait-wait-dont-tell-me/id121493804?uo=2&uo=2 
#=> Stuff You Should Know: http://itunes.apple.com/us/podcast/stuff-you-should-know/id278981407?uo=2&uo=2 

... или, возможно, это:

# Convert XML entries into an array of hashes 
parsed = itunes_top_300.xpath('//entry').map do |entry| 
    name = entry.xpath("name").text 
    url = entry.xpath("link/@href").text 
    { name:name, url:url } 
end 

require 'pp' 
pp parsed[0..3] 
#=> [{:name=>"This American Life", 
#=> :url=>"http://itunes.apple.com/us/podcast/this-american-life/id201671138?uo=2&uo=2"}, 
#=> {:name=>"NPR: Wait Wait... Don't Tell Me! Podcast", 
#=> :url=>"http://itunes.apple.com/us/podcast/npr-wait-wait-dont-tell-me/id121493804?uo=2&uo=2"}, 
#=> {:name=>"Stuff You Should Know", 
#=> :url=>"http://itunes.apple.com/us/podcast/stuff-you-should-know/id278981407?uo=2&uo=2"}, 
#=> {:name=>"Freakonomics Radio", 
#=> :url=>"http://itunes.apple.com/us/podcast/freakonomics-radio/id354668519?uo=2&uo=2"}] 
Смежные вопросы