2014-07-07 4 views
1

Ruby를 웹 사이트로 이동시키고 캠페인 목록을 반복하고 특정 데이터를 페이지를 긁어 냈습니다. 내가 지금 가지고있는 문제는 Nokogiri가 나에게 줄 수있는 구조에서 그것을 얻고 그것을 읽을 수있는 형태로 출력하는 것이다.HTML 태그없이 Nokogiri 출력 구성하기

{"views":[[17,145],[18,165],[19,99],[20,71],[21,31],[22,26],[23,10],[0,15],[1,1],  [2,18],[3,19],[4,35],[5,47],[6,44],[7,67],[8,179],[9,141],[10,112],[11,95],[12,46],[13,82],[14,79],[15,70],[16,103]],"orders":[[17,10],[18,9],[19,5],[20,1],[21,1],[22,0],[23,0],[0,1],[1,0],[2,1],[3,0],[4,1],[5,2],[6,1],[7,5],[8,11],[9,6],[10,5],[11,3],[12,1],[13,2],[14,4],[15,6],[16,7]],"conversion_rates":[0.06870229007633588,0.05442176870748299,0.050505050505050504,0.014084507042253521,0.03225806451612903,0.0,0.0,0.06666666666666667,0.0,0.05555555555555555,0.0,0.02857142857142857,0.0425531914893617,0.022727272727272728,0.07462686567164178,0.06134969325153374,0.0425531914893617,0.044642857142857144,0.031578947368421054,0.021739130434782608,0.024390243902439025,0.05063291139240506,0.08571428571428572,0.06741573033707865]} 

배열이 { views [[hour, # of views], [hour, # of views], etc. } 스탠드 :

campaign_list = Array.new 
campaign_list.push(1042360, 1042386, 1042365, 992307) 

browser = Watir::Browser.new :chrome 
browser.goto '<redacted>' 
browser.text_field(:id => 'email').set '<redacted>' 
browser.text_field(:id => 'password').set '<redacted>' 
browser.send_keys :enter 

file = File.new('hourlysales.csv', 'w') 
data = {} 

campaign_list.each do |campaign| 
    browser.goto "<redacted>" 

    if browser.text.include? "Application Error" 
    puts "Error loading page, I recommend restarting script" 
    # Possibly automatic restart of script 
    else 
    hourly_data = Nokogiri::HTML.parse(browser.html).text 
    # file.write data 
    puts hourly_data 
    end 

내가 얻을 출력됩니다. 명령과 동일합니다. 나는 전환율이 필요 없다.

또한 각 키의 값을 추가해야하므로 5 페이지에 대해이 작업을 수행 한 후 하루 중 각 시간에 대해 하나의 키와 해당 시간의 총보기 수가 있습니다. 두세 번 시도했는데 아무런 진전을 이루지 못했습니다.

여러분의 도움을 주시면 감사하겠습니다.

+0

'hourly_data'가 JSON 인 것처럼 보입니다. 그 맞습니까? –

+0

CSV 파일을 생성 중이므로 [Ruby에 내장 된 CSV] (http://www.ruby-doc.org/stdlib-2.1.2/libdoc/csv/rdoc/CSV.html) 클래스를 사용하십시오. 데이터가 단지 숫자 데이터이면 CSV는 약간의 번거 로움을 덜어줍니다. 데이터에 문자열, 특히 쉼표와 따옴표가 포함 된 문자열이 포함 된 경우 CSV를 사용하면 많은 문제를 해결할 수 있습니다. 사전 발명 된 바퀴를 사용하는 습관을 갖게되는 것이 현명합니다. –

답변

1

출력 (코드에서 가정 한 내용은 hourly_data)은 JSON입니다. 이 경우 숫자를 쉽게 파싱하고 더할 수 있습니다. 이 같은 것을 :

require "json" # at the top of your script 
# ... 

def sum_hours_values(data, hours_values=nil) 
    # Start with an empty hash that automatically initializes missing keys to `0` 
    hours_values ||= Hash.new {|hsh,hour| hsh[hour] = 0 } 

    # Iterate through the [hour, value] arrays, adding `value` to the running 
    # count for that `hour`, and return `hours_values` 
    data.each_with_object(hours_values) do |(hour, value), hsh| 
    hsh[hour] += value 
    end 
end 

# ... Watir/Nokogiri stuff here... 

# Initialize these so they persist outside the loop 
hours_views, orders_views = nil 

campaign_list.each do |campaign| 
    browser.goto "<redacted>" 

    if browser.text.include? "Application Error" 
    # ... 
    else 
    # ... 

    hourly_data_parsed = JSON.parse(hourly_data) 

    hours_views = sum_hours_values(hourly_data_parsed["views"], hours_views) 
    hours_orders = sum_hours_values(hourly_data_parsed["orders"], orders_views) 
    end 
end 

puts "Views by hour:" 
puts hours_views.sort.map {|hour_views| "%2i\t%4i" % hour_views } 

puts "Orders by hour:" 
puts hours_orders.sort.map {|hour_orders| "%2i\t%4i" % hour_orders } 

P.S. sum_hours_values의 멋진 재귀 버전이 있습니다. 반복 버전이 대부분의 Ruby 프로그래머에게 더 명확하기 때문에 포함하지 않았습니다. 당신이 재귀에 빠지면 나는 그것을 당신을위한 운동으로 남겨 둡니다. ;)

+0

당신이 저에게 준 스크립트 코드를 스크립트에 통합했지만 이제는 '+'오류가 발생합니다 : 해시를 Fixnum (TypeError)으로 강요 할 수 없습니다. 문제는 값을 증가시키는 sum_hours_values ​​함수의 끝에 있습니다. 어떤 아이디어? – user3813158

+0

죄송합니다 @ user3813158, 나는'each_with_object'에 대한 블록 인수로 실수를 저질 렀습니다. 이제 해결되었습니다. –

관련 문제