如何解析相关数据并将值存储到数据库
我试图通过网页解析,收集值并将它们存储到数据库中。如何解析相关数据并将值存储到数据库
这里是我的代码注释的数据库代码:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open("https://example.com/colors"))
colors = doc.css(".colorCircle")
colors_name = doc.css(".zw-m-c-txt")
colors.each do |ele|
hex_code = ele.attr('style').split(";").first.split(":").last
colors_name.each do |name|
color_name = name.text
puts " ++++++ hex_code #{hex_code}"
puts " ++++++ color_name #{color_name}"
# color = colors.find_by(:hex_code => hex_code)
# if color.present?
# color.update_attributes(:name => color_name)
# else
# model.colors.create(:name => color_name, :hex_code => hex_code)
# end
end
end
下面是HTML源页面的细节:
<span class="colorCircle" style="background-color:#EEEFF4;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> White Orchid Pearl </span></p>
<span class="colorCircle" style="background-color:#ACABB0;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Modern Steel Metallic </span></p>
<span class="colorCircle" style="background-color:#220909;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Golden Brown Metallic </span></p>
<span class="colorCircle" style="background-color:#43161b;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Carnelian Red Pearl </span></p>
<span class="colorCircle" style="background-color:#E8F1FA;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Alabaster Silver </span></p>
我无法遍历它依次存储到数据库。下面是电流输出:
++++++ color_name White Orchid Pearl
++++++ hex_code #EEEFF4
++++++ color_name White Orchid Pearl
++++++ hex_code #ACABB0
++++++ color_name White Orchid Pearl
++++++ hex_code #220909
++++++ color_name White Orchid Pearl
++++++ hex_code #43161b
++++++ color_name White Orchid Pearl
++++++ hex_code #E8F1FA
++++++ color_name Modern Steel Metallic
++++++ hex_code #EEEFF4
++++++ color_name Modern Steel Metallic
++++++ hex_code #ACABB0
++++++ color_name Modern Steel Metallic
++++++ hex_code #220909
++++++ color_name Modern Steel Metallic
++++++ hex_code #43161b
++++++ color_name Modern Steel Metallic
这是预期的输出:
hex_code #EEEFF4
color_name White Orchid Pearl
hex_code #ACABB0
color_name Modern Steel Metallic
hex_code #220909
color_name Golden Brown Metallic
如何获得预期的输出,并将其保存到颜色名称对应的hex_code
数据库?
这里就是我会做,如果我想这些数据:
data.each do |k, v|
puts "hex_code: %s\ncolor_name: %s" % [k, v]
end
将输出:
hex_code: EEEFF4
color_name: White Orchid Pearl
hex_code: ACABB0
color_name: Modern Steel Metallic
hex_code: 220909
color_name: Golden Brown Metallic
hex_code: 43161b
color_name: Carnelian Red Pearl
hex_code: E8F1FA
color_name: Alabaster Silver
不过,也有当用于
require 'nokogiri'
doc = Nokogiri::HTML(DATA.read)
data = doc.search('.colorCircle').map { |span|
hex = span['style'][/#([^;]+);$/, 1]
color = span.next_element.at('span').text.strip
[ hex, color ]
}.to_h
# => {"EEEFF4"=>"White Orchid Pearl",
# "ACABB0"=>"Modern Steel Metallic",
# "220909"=>"Golden Brown Metallic",
# "43161b"=>"Carnelian Red Pearl",
# "E8F1FA"=>"Alabaster Silver"}
__END__
<span class="colorCircle" style="background-color:#EEEFF4;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> White Orchid Pearl </span></p>
<span class="colorCircle" style="background-color:#ACABB0;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Modern Steel Metallic </span></p>
<span class="colorCircle" style="background-color:#220909;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Golden Brown Metallic </span></p>
<span class="colorCircle" style="background-color:#43161b;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Carnelian Red Pearl </span></p>
<span class="colorCircle" style="background-color:#E8F1FA;"></span>
<p class="zw-m-c-txt"> <span class="fnt-14"> Alabaster Silver </span></p>
其中,与这些协会互联网上的桌子。我建议找一个并创建一个将数据存储为常量或散列的模块或类,而不是解析一个并尝试将其注入到数据库表中,我建议找到一个模块或类,以便不必触击数据库即可提取值。如果您使用这些值设置页面颜色,或者即使您正在呈现值与颜色名称的相关性,也希望访问速度最快。或者创建一个已经呈现的静态页面,因为这些关联和定义不会改变。
数据库对于某些事情来说很棒,但对于它来说这似乎不是个好时机。
这
ele.attr('style').split(";").first.split(":").last
是残酷的。
从字符串中提取十六进制代码是字符串切片或正则表达式的绝佳应用。你可以这样做多种方式:
style = "background-color:#EEEFF4;"
style.split(':').last.chop # => "#EEEFF4"
style[-8..-2] # => "#EEEFF4"
style[/(#\h{3,6});$/, 1] # => "#EEEFF4"
使用切片[-8..-2]
可能是最容易出错的,因为它假定值始终为六个字符长,这对于颜色的十六进制值不必须。例如#FFF
相当于#FFFFFF
,因此处理三个或六个字符变体很重要。
在我上面的示例中,我使用了/#([^;]+);$/
,它不像/(#\h{3,6});$/
那么简洁,但是他们都有权衡,所以如果要使用正则表达式,请选择。他们的工作方式是让你弄清楚,只要记住,并非所有事情都有机会用金色正则表达式锤击数据;当他们是最好的工具时使用它们,因为它们可以打开黑暗的大门,迎来虫子的主宰。
而且,我特意排除在十六进制值#
。添加它会浪费冗余字符上的空间以进行查找和表格,但是您的里程可能会有所不同。
谢谢@theTinMan,非常好的解释。 –
你的代码工作,如果我从DATA.read读取数据,但是如果我尝试直接从网络读取数据我得到以下error.'在
我无法帮助你,因为我不知道你从哪里读取数据。 “[mcve]”表示在问题中您需要一个最小输入示例来演示我使用的问题,因此您提供的HTML可能不准确。我建议在命令行中使用'nokogiri'并将它传递给您正在使用的URL,然后查看您是否可以找到要查找的节点。它可能是页面使用DHTML,只有浏览器才能找到它。 –
所以你想要将每个颜色名称与跨度的背景颜色关联起来?例如。白色兰花珍珠#EEEFF4? – radubogdan
你意识到你有两个嵌套for循环,你基本上通过每个color_name运行每种颜色。 – radubogdan
@radubogdan是的你是正确的,我想将每个颜色名称与span的bkg-color相关联。 –