2017-04-06 70 views
0

我試圖通過網頁解析,收集值並將它們存儲到數據庫中。如何解析相關數據並將值存儲到數據庫

這裏是我的代碼註釋的數據庫代碼:

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數據庫?

+0

所以你想要將每個顏色名稱與跨度的背景顏色關聯起來?例如。白色蘭花珍珠#EEEFF4? – radubogdan

+0

你意識到你有兩個嵌套for循環,你基本上通過每個color_name運行每種顏色。 – radubogdan

+0

@radubogdan是的你是正確的,我想將每個顏色名稱與span的bkg-color相關聯。 –

回答

1

這裏就是我會做,如果我想這些數據:

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});$/那麼簡潔,但是他們都有權衡,所以如果要使用正則表達式,請選擇。他們的工作方式是讓你弄清楚,只要記住,並非所有事情都有機會用金色正則表達式錘擊數據;當他們是最好的工具時使用它們,因爲它們可以打開黑暗的大門,迎來蟲子的主宰。

而且,我特意排除在十六進制值#。添加它會浪費冗餘字符上的空間以進行查找和表格,但是您的里程可能會有所不同。

+0

謝謝@theTinMan,非常好的解釋。 –

+0

你的代碼工作,如果我從DATA.read讀取數據,但是如果我嘗試直接從網絡讀取數據我得到以下error.'在

塊:在'nil:NilClass(NoMethodError)'注意' span'只包含一行''它不包含下一個標籤。所以我試着在搜索'data = doc.search('。colorCircle,.zw-m-c-txt')。map'中指定兩個類,但仍然得到上面提到的錯誤。你能指導我哪裏出錯了嗎? –

+0

我無法幫助你,因爲我不知道你從哪裏讀取數據。 「[mcve]」表示在問題中您需要一個最小輸入示例來演示我使用的問題,因此您提供的HTML可能不準確。我建議在命令行中使用'nokogiri'並將它傳遞給您正在使用的URL,然後查看您是否可以找到要查找的節點。它可能是頁面使用DHTML,只有瀏覽器才能找到它。 –

相關問題