2010-12-15 24 views
1

私は単純なスクリーンスクレイピングスクリプトを書いており、スクリプトの終わりには、activerecord挿入の準備として配列の配列を作成しようとしています。次のように私が達成しようとしている構造がある:私は、配列が空の配列bをプリントアウトしようとすると、配列の配列を作成するためのRubyスクリプト

配列Bは現在、10の素子アレイ

b = [[0,1,2,3,4,5,6,7,8,9],[0,1,2,3,4,5,6,7,8,9],[0,1,2,3,4,5,6,7,8,9]] 

のシリーズを保持しています。私はまだ、ルビーとプログラミングについてはかなり新しく、配列bで値を取得し、スクリプト全体を改善する方法についてのフィードバックを感謝しています。スクリプトは次のとおりです。

require "rubygems" 
require "celerity" 
t = 0 
r = 0 
c = 0 
a = Array.new(10) 
b = Array.new 

    #initialize Browser 
    browser = Celerity::IE.new 
    #goto Login Page 
    browser.goto('http://www1.drf.com/drfLogin.do?type=membership') 
    #input UserId and Password 
    browser.text_field(:name, 'p_full_name').value = 'username' 
    browser.text_field(:name, 'p_password').value = 'password' 
    browser.button(:index, 2).click 
    #goto DRF Frontpage 
    browser.goto('http://www.drf.com/frontpage') 
    #goto DRF Entries 
    browser.goto('http://www1.drf.com/static/indexMenus/eindex.html') 
    #click the link to access the entries 
    browser.link(:text, '09').click 

    browser.tables.each do |table| 
    t = t + 1 
     browser.table(:index, t).rows.each do |row| 
     r = r + 1 
      browser.table(:index, t).row(:index, r).cells.each do |cell| 
      a << cell.text 
      end 
      b << a 
      a.clear   
     end 
     r = 0 
    end 
    puts b 
    browser.close 
+1

大量のスクリプトをポストするのではなく、 'browser'を扱う行を簡単に置き換えることができますので、[もっと小さく自己完結した例](http://sscce.org/)が生成されます。つまり、このサンプルはユーザー名とパスワードなしで実行可能ではなく、少なくともこの質問に関する限り、コードの少なくとも半分は無関係です。 – outis

答えて

2

これよりルビーのような方法にあなたのメインループのマイナーな書き換えを。

b = Array.new 
browser.tables.each_with_index do |table, t| 
    browser.table(:index, 1 + t).rows.each_with_index do |row, r| 
    a = Array.new(10) 
    browser.table(:index, 1 + t).row(:index, 1 + r).cells.each do |cell| 
     a << cell.text 
    end 
    b << a 
    end 
end 
puts b 

私は配列の初期化を必要な場所のすぐ上に移動しました。それはもちろんプログラマが選ぶことです。

上記の2つのカウンタ変数を作成するのではなく、0から始まるインデックス変数を追加するeach_with_indexを使用しました。 1オフセットを取得するには、1を追加します。

これは大きな変更ではありませんが、より固着性の高いアプリケーションになります。

私がそれを見る1つの問題は、ループ外にaアレイを作成してから、bに割り当てるときに再利用することです。つまり、同じ配列が使用されるたびにクリアされ、値がその配列に格納されます。以前の配列の値は上書きされますが、重複した配列がbになります。

require 'pp' 

a = [] 
b = [] 

puts a.object_id 

a[0] = 1 
b << a 
a.clear 

a[0] = 2 
b << a 

puts 
pp b 
b.each { |ary| puts ary.object_id } 
# >> 2151839900 
# >> 
# >> [[2], [2]] 
# >> 2151839900 
# >> 2151839900 

aアレイが繰り返し再利用されることに注意してください。私は二番目の配列にaを変更した場合は

は、Bのための2つの値があり、2つの別々のオブジェクトです:

require 'pp' 

a = [] 
b = [] 

puts a.object_id 

a[0] = 1 
b << a 
a = [] 

a[0] = 2 
b << a 

puts 
pp b 
b.each { |ary| puts ary.object_id } 
# >> 2151839920 
# >> 
# >> [[1], [2]] 
# >> 2151839920 
# >> 2151839780 

がうまくいけば、それはあなたが将来的に問題を回避するのに役立ちます。

+0

はい、それはかなり役に立ちます。ありがとう.... – Mutuelinvestor

+0

問題はありません。ポインタの扱いAKAのオブジェクトや構造への参照は、プログラミングを学ぶ際に最初に取り除かなければならないハードルの1つです。彼らはあなたがそれらを酔わせて、そして本当に強力ですが、あなたはその間に少しずつ得るでしょう。 Rubyは私たちをそれらから隔離します。私はPerlやC言語でプログラムできないと思う。 :-) –

+0

@Mutuelinvestor、配列を正しく取り込むようにしましたか?あなたの現在の状態で元の質問を更新しない場合、我々はそれに取り組んでいきます。 –

2

あなたの問題は、最後にあります:

b << a # push a *reference to* a onto b 
a.clear # clear a; the reference in b now points to an empty array! 

あなたはa.clearとでそのループを開始するための参照削除する場合:

browser.tables.each do |table| 
    t = t + 1 
    a = [] 

を...あなたは金色になります(少なくともあなたのアレイビルが行く限り)

+0

応答のためのビルのおかげで。私はこれを試して、今は配列のデータを取得しています。残念ながら、10個の要素(つまりデータの行)で1つの配列を取得する代わりに、10個の要素で10個の配列を取得しています。したがって、私はr = r + 1の下でa = []を下に移動して、これは私が探しているものを与えるだろうと思っています。 – Mutuelinvestor

1

私はあなたの質問から複数のタブレットがあるかどうかは分かりませんesかどうか。多分ただ一つ?その場合:あなたは複数のテーブルを持っているし、本当にアレイ(セル)のアレイ(列)の配列(テーブル)をしたい場合は

b = browser.tables.first.rows.map {|row| row.cells.map(&:text)} 

は、それは

b = browser.tables.map {|t| t.rows.map {|row| row.cells.map(&:text)}} 

とテーブル場合だろうすべてが同じ構造を持っていて、ちょうど彼らが一つの大きなテーブルにあったかのように、あなたが行うことができますすべての行をしたい:

b = browser.tables.map {|t| t.rows.map {|row| row.cells.map(&:text)}}.flatten(1) 
+0

グレンは返信してくれてありがとう。私は実際には複数のテーブルを持っています。私は地図のコマンドに慣れていないので、私は少し研究を行うと、私はあなたの提案を起動します。複数のテーブルのシナリオの下で、あなたの応答はどのように変化しますか? – Mutuelinvestor

+0

すべてのテーブルの行構造は同じですか?または、本当に配列(セル)の配列(行)の配列(テーブル)が必要ですか? –

+0

テイルズは同じ行とセル構造を持っています。私はバルクインサートを使用してデータベースにデータを挿入しています。Gem:http://rorstuff.blogspot.com/2010/05/activerecord-bulk-insertion-of-data-in.html私のデータには通常、8〜10個のテーブルがあります各テーブルは5〜12行のどこかにある。各行には10個のセル(td)があります。これは、あなたの2番目の選択肢が私が達成しようとしているものと一貫していると仮定して正しい場合です。 – Mutuelinvestor

関連する問題