2012-02-13 12 views
1

テーブルがあり、Nokogiriを使用して各テーブル行の最初の2つのセルの内容を抽出します。現在、私はいくつかの困難に直面しており、あなたから助けを受けたいと思っています。これは私が今取得するものです。誰でも私を助けることができますか?ありがとう。Nokogiriを使用して、すべてのテーブル行の最初の2つのテーブルセルを抽出します。

irb(main):001:0> require 'nokogiri' 
=> true 
irb(main):002:0> 
irb(main):003:0* @doc = Nokogiri::HTML::DocumentFragment.parse <<-EOHTML 
irb(main):004:0" <body> 
irb(main):005:0" <div class="c"> 
irb(main):006:0" <table> 
irb(main):007:0"  <tr> 
irb(main):008:0"   <td>test</td><td>test</td><td>test</td><td>test</td> 
irb(main):009:0"  </tr> 
irb(main):010:0"  <tr class="even"> 
irb(main):011:0"   <td>test</td><td>test</td><td>test</td><td>test</td> 
irb(main):012:0"  </tr> 
irb(main):013:0"  <tr> 
irb(main):014:0"   <td>test</td><td>test</td><td>test</td><td>test</td> 
irb(main):015:0"  </tr> 
irb(main):016:0"  <tr class="even"> 
irb(main):017:0"   <td>test</td><td>test</td><td>test</td><td>test</td> 
irb(main):018:0"  </tr> 
irb(main):019:0" </table> 
irb(main):020:0" </div> 
irb(main):021:0" </body> 
irb(main):022:0" EOHTML 
irb(main):026:0> @doc.css("div.c > table").search("table/tr/td") 
=> ... 
irb(main):026:0> @doc.css("div.c > table").search("table/tr/td[position()>2]") 
Nokogiri::CSS::SyntaxError: unexpected '>' after '#<Nokogiri::CSS::Node:0x2b7bc20>' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/css/parser_extras.rb:87:in `on_error' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/1.9.1/racc/parser.rb:99:in `_racc_do_parse_c' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/1.9.1/racc/parser.rb:99:in `do_parse' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/css/parser_extras.rb:62:in `parse' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/css/parser_extras.rb:79:in `xpath_for' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/css.rb:23:in `xpath_for' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:111:in `block (2 levels) in 
css' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:109:in `map' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:109:in `block in css' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:239:in `block in each' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:238:in `upto' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:238:in `each' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:105:in `css' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:83:in `block in search' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:80:in `each' 
     from C:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/nokogiri-1.5.0-x86-mingw32/lib/nokogiri/xml/node_set.rb:80:in `search' 
     from (irb):27 
     from C:/RailsInstaller/Ruby1.9.2/bin/irb:12:in `<main>'irb(main):028:0> 

答えて

3

あなたは、同じ行のセル内の論理的な関係を維持したいコメントで言ったので:あなたが効率的に一度にすべてのテキストを抽出したい場合は

@doc.css('div.c > table > tr').each do |tr| 
    td1, td2 = tr.xpath('./td') # Find only direct child items 
    # td1 is the first <td>, td2 the second 
end 

data = @doc.css('tr').map do |row| 
    # Find the text for all td, get the first two, then join with ' - ' 
    row.xpath('./td').map(&:text)[0,2].join(' - ') 
end 

puts data 
#=> a1 - b1 
#=> a2 - b2 
#=> a3 - b3 
#=> a4 - b4 

上記の出力は、すべての「テスト」よりも面白いテストデータから得られたものです。

3

XPathクエリを使用する:

@doc.xpath('//table/tr/td[1] | //table/tr/td[2]') 

これは親としてtableノードを有するtrノード内の第一及び第二tdノードを返します。

+0

こんにちはVivien、あなたのメソッドは、すべての一致したテーブルのセルを同じ方法で扱います。実際、私の例では、各行の2つのセルには何らかの関係があるため、それらの値が必要です。それらを抽出してそれらの関係を予約する方法はありますか?たとえば、すべての行の最初の2つのセルを取得して連結する方法はありますか?ありがとう。 –

+0

@Yousui最初の 'td'を取り出し、それを反復するときは[' td.next_element'](http://nokogiri.org/Nokogiri/XML/Node.html#method-i-ext_element)を使ってその行の第2の 'td'。 – Phrogz

1

は私がSAXパーサ

class ShowtimeDaily < Nokogiri::XML::SAX::Document 
    attr_reader :td_count 
    def start_element name, attrs =[] 
    case name 
    when 'tr' 
    @td_count = 0 
    when 'td' 
    @td_count +=1 
    end 

def characters string 
    # string containts the content you'd be requiring 
    puts "content of row number #{@td_count}: #{string}" if @td_count < 3 
end 

私はそれを検証していないとして、おそらくその中のエラーを持つことになる書いたコードを使用してお勧めしたいです。私はそれがあなたの問題を解決するうえで役立つことを願っています。

+1

絶対に必要な場合を除いて、SAXパーサーを使用することはお勧めしません(メモリ制限が当てられ、プル解析はオプションではありません)。 APIは恐ろしいです。 –

関連する問題