gpt4 book ai didi

ruby-on-rails - 使用 Nokogiri 解析 HTML - The Ruby/Rails Way

转载 作者:太空宇宙 更新时间:2023-11-03 18:17:54 25 4
gpt4 key购买 nike

我正在制作一个小型 Rails 应用程序来解析来自本地公共(public)广播电台的 HTML 播放列表并显示当前正在播放的歌曲。

我创建了一个类来为播放列表中的歌曲建模,如下所示:

require 'open-uri'

class Song

attr_accessor :artist, :title, :album, :playtime

def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end

def self.latest(how_many)
html = Nokogiri::HTML(open(Rails.configuration.on_air_url))
rows = html.css('#table_tracklist tbody tr')
rows.take(how_many).map do |row|
parse_song(row)
end
end

private

def self.parse_song(row)
artist = row.css('.artist').text
playtime = row.css('.time span').text
title = row.css('.song').text
album = row.css('.album').text
Song.new({ artist: artist, playtime: playtime, title: title, album: album })
end

end

我有几个问题:

  1. 我没有使用任何 ActiveRecord 或 ActiveModel 功能。这是否仍然属于我的 models 目录中的一个类,还是我应该将它重构为 lib 中的一个类?我正计划拥有一个 Controller ,其唯一目的是将通过 JSON 播放的最新歌曲返回给客户端。有没有更好的方法?
  2. 我对 Song::latest 方法很满意,但我觉得应该有一种更优雅的方法来处理 Song::parse_song。我正在考虑更改模型的属性以匹配播放列表使用的 CSS 类的名称,并使用我想要获取的属性名称数组,但由于存在“时间”字段的特殊情况(我想要捕获跨度的文本)这样看起来会更清楚。你能提供一些建议吗?

我认为删除我的初始化方法并执行类似的操作会更好。想法? [注意:在下面合并了铁皮人的回答。]

  def self.parse_song(row)
song = Song.new
song.artist = row.at_css('.artist').text
song.playtime = row.at_css('.time span').text
song.title = row.at_css('.song').text
song.album = row.at_css('.album').text
song
end

最佳答案

你不明白什么css做:

artist = row.css('.artist').text
playtime = row.css('.time span').text
title = row.css('.song').text
album = row.css('.album').text

应该是:

artist = row.at('.artist').text
playtime = row.at('.time span').text
title = row.at('.song').text
album = row.at('.album').text

css , 比如 searchxpath返回 NodeSet .一个 NodeSet 就像一个 Node 的数组秒。即使您知道文档中只有一个匹配元素,css 仍会返回一组。如果特定选择器有多个命中,您将收到所有匹配的节点。

当您在 NodeSet 上使用 text 时,您将获得节点中所有文本的串联字符串,这很可能不是您想要的:

require 'nokogiri'

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

doc.css('p').text # => "foobar"

此外,Nokogiri 非常宽容/理解我们用来与之对话的代码。我们不必使用 css , 或 xpath , 我们可以使用 search让 Nokogiri 判断选择器是 CSS 还是 XPath:

require 'nokogiri'

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

doc.css('p').size # => 2
doc.search('p').size # => 2

at也是如此, at_cssat_xpath :

require 'nokogiri'

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

doc.at_css('p').text # => "foo"
doc.at('p').text # => "foo"

我建议偷懒并使用 searchat在 99.9% 的情况下,您编写代码搜索节点,然后在您必须向 Nokogiri 提示选择器是什么的极少数情况下使用 CSS/XPath 变体。

关于ruby-on-rails - 使用 Nokogiri 解析 HTML - The Ruby/Rails Way,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23224638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com