ザ・インタビューズをテキストに変換するRubyスクリプト Revisited

http://qiita.com/hyuki/items/25731079d8a6129e81d5

普通にNokogiri::XML::SAX::Documentを使った場合

```rb:hyuki_interviews_nokogiri.rb
#!/usr/bin/ruby
#coding:utf-8
require 'rubygems'
require 'nokogiri'
require 'uri'
require 'net/http'

1.step(123){|i|

body=''
uri=URI.parse('http://theinterviews.jp/hyuki/page/'+i.to_s)
Net::HTTP.start(uri.host){|http|
	body=http.get(uri.path).response.body
}
body.gsub!(/\<br[^\>]*\>/,'') #lol

listener=Class.new(Nokogiri::XML::SAX::Document){
	def initialize
		@content=Hash.new{|h,k|h[k]=[]}
		@current_tag=[]
		@attrs=nil
	end
	attr_reader :content

	def start_element(tag,attrs)
		@current_tag.push(tag)
		@attrs=attrs
	end
	def end_element(tag)
		if (t=@current_tag.pop)!=tag then raise "xml is malformed /#{t}" end
	end
	def cdata_block(text)
	end
	def characters(text)
		text.strip!
		return if text.empty?
		if @current_tag==['html','body','div','div','div','div','div','div','div','h1','a']
			@content['title']<< text.gsub("\r",'')
		elsif @current_tag==['html','body','div','div','div','div','div','div','div']&&@attrs
			cls=@attrs.assoc('class')
			if cls&&cls.last=='note'
				@content['note']<< text.gsub("\r",'')
			end
		elsif @current_tag==['html','body','div','div','div','div','div','div','div','p']
			@content['date']<< text.gsub("\r",'')
		end
	end
	def comment(text)
	end
}.new
Nokogiri::HTML::SAX::Parser.new(listener).parse(body)
listener.content['title'].zip(listener.content['note'],listener.content['date']).each{|title,note,date|
	puts "# 質問"
	puts
	puts title
	puts
	puts "# 解答"
	puts
	puts note
	puts date
	puts '---------------'
	puts
}

sleep(1)}
```

multisax ( https://rubygems.org/gems/multisax )を使った場合
nokogiri版からの変更はわずかですが、nokogiriとox ( https://rubygems.org/gems/ox )のどちらか片方がインストールされていれば問題なく動作します。

```rb:hyuki_interviews_multisax.rb
#!/usr/bin/ruby
#coding:utf-8
require 'rubygems'
require 'multisax'
require 'uri'
require 'net/http'

1.step(123){|i|

body=''
uri=URI.parse('http://theinterviews.jp/hyuki/page/'+i.to_s)
Net::HTTP.start(uri.host){|http|
	body=http.get(uri.path).response.body
}
body.gsub!(/\<br[^\>]*\>/,'') #lol
MultiSAX::Sax.open(:HTML)
listener=MultiSAX::Sax.parse(body,Class.new{
	include MultiSAX::Callbacks
	def initialize
		@content=Hash.new{|h,k|h[k]=[]}
		@current_tag=[]
		@attrs=nil
	end
	attr_reader :content

	def sax_tag_start(tag,attrs)
		@current_tag.push(tag)
		@attrs=attrs
	end
	def sax_tag_end(tag)
		if (t=@current_tag.pop)!=tag then raise "xml is malformed /#{t}" end
	end
	def sax_cdata(text)
	end
	def sax_text(text)
		text.strip!
		return if text.empty?
		if @current_tag==['html','body','div','div','div','div','div','div','div','h1','a']
			@content['title']<< text.gsub("\r",'')
		elsif @current_tag==['html','body','div','div','div','div','div','div','div']&&@attrs
			if @attrs['class']=='note'
				@content['note']<< text.gsub("\r",'')
			end
		elsif @current_tag==['html','body','div','div','div','div','div','div','div','p']
			@content['date']<< text.gsub("\r",'')
		end
	end
	def sax_comment(text)
	end
}.new)
listener.content['title'].zip(listener.content['note'],listener.content['date']).each{|title,note,date|
	puts "# 質問"
	puts
	puts title
	puts
	puts "# 解答"
	puts
	puts note
	puts date
	puts '---------------'
	puts
}

sleep(1)}
```