今日も元気にテクニカル

技術情報書きたいけど本ブログに書きたくないからこんな名前になりました。

newsingの新着pickupゲット復習

結局こういうコードにしました。

require 'hpricot'
require 'open-uri'
require 'kconv'

list = Array.new
maxtop = 10 # maxtop*(10+1)分の記事を取得する。

# 0〜maxtop分のnewsingユニークURL取得----------------------------------

0.upto(maxtop) do |i|
  doc = Hpricot(open(%Q[http://newsing.jp/list?start=#{i}0]))
    elem = (doc/%Q[/html/body/table[1]/tr[2]/td[2]/table[3]/tr/td[1]/div/table[1]/tr[1]/td[3]/table[3]/tr[1]/td[1]/a[1]]).each do |elem|
      list << elem.to_html.tosjis.sub(%r[\n.*],"").sub(%Q[<a href="],"").sub(%Q[" class="medium">],"")
    end
end

配列listにnewsingのpickupURLが入る、と。で、それぞれのURLをHpricotで開いて内容を取得する。

list.each do |url|
  # 記事部分-----------------------------------------------------------
  doc = Hpricot(open(url))
  entry = (doc/%Q[/html/body/table[1]/tr[2]/td[2]/table[3]/tr[1]/td[1]/div[1]/table[1]/tr[1]/td[1]/table[1]/tr[1]])
  # 記事タイトル
  title = (entry/%Q[/td[3]/div[1]/h3[1]/]).inner_text.tosjis
  # 記事"概要"(aタグ消えるからinner_text禁止)
  main_text = (entry/%Q[/td[3]/table[1]/tr[1]/td[1]/div[1]/]).to_html.tosjis.sub(%Q[<!--記事内容-->],"")
  # picker名
  picker = (entry/%Q[/td[3]/table[2]/tr[1]/td[2]/]).to_html.tosjis.gsub("\n","").sub(%r[^.*<!--Picker名--><a href="http://newsing.jp/user/.*?">],"").sub(%r[</a>.*],"")
  # 時間
  picktime = (entry/%Q[/td[3]/table[2]/tr[1]/td[2]/]).to_html.tosjis.gsub("\n","").sub(%r[^.*</a>&nbsp;],"").gsub(%r[^\s*],"").strip
  # 支持
  picker_eval = (entry/%Q[/td[3]/table[3]/tr[1]/td[1]/]).to_html.tosjis.gsub("\t","").gsub("\n","").sub(%r[.*height="18" alt="],"").sub(%r[" align="absmiddle".*$],"")
  # コメント内容
  picker_com = (entry/%Q[/td[3]/table[3]/tr[1]/td[1]/]).to_html.tosjis.gsub("\t","").gsub("\n","").gsub("\r","").sub(%r[^.*width="20" />&nbsp;],"").gsub(%r[^\s*],"")
  # ptや○×数など取得
  pt = (entry/%Q[/td[1]/script[1]/]).to_html.tosjis.gsub("\n","").sub(%r[.*\(],"").sub(%r[\).*],"").split("&#39;, &#39;")

  # コメント部分--------------------------------------------------
  comment = (doc/%Q[/html/body/table[1]/tr[2]/td[2]/table[3]/tr[1]/td[1]/table[2]])

  arr1 = Array.new
  arr2 = Array.new
  arr3 = Array.new
  arr4 = Array.new
  arr5 = Array.new
  
  1.upto(pt[3].to_i + pt[4].to_i) do |i|
    # コメントした人
    arr1 << (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[1]/td[3]/a[2]]).inner_html.tosjis
    # コメントした時間
    arr2 << (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[1]/td[3]/]).to_html.tosjis.gsub("\n","").sub(%r[.*&nbsp;],"").strip
    # 支持する
    if /支持する/ =~ (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[1]/td[1]/]).to_html.tosjis
      arr3 << ""
      # 支持するコメント内容
      arr4 << (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[2]/td[2]/div[1]/]).to_html.tosjis.gsub("\r","").gsub("\n","").sub(%r[^\s*],"").sub(%r[<script type="text/javascript">.*],"")
      # nicecomment数値
      arr5 << (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[2]/td[2]/div[1]/script[1]/]).to_html.tosjis.gsub("\r","").gsub("\n","").sub(%r[^.*\(&#39;],"").sub(%r[&#39;\).*],"").split("&#39;, &#39;")[1]
    else
      arr3 << "×"
      # 支持しないコメント内容
      arr4 << (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[2]/td[3]/div[1]/]).to_html.tosjis.gsub("\r","").gsub("\n","").sub(%r[^\s*],"").sub(%r[<script type="text/javascript">.*],"")
      # nicecomment数値
      arr5 << (comment/%Q[/tr[1]/td[1]/table[#{i}]/tr[2]/td[3]/div[1]/script[1]/]).to_html.tosjis.gsub("\r","").gsub("\n","").sub(%r[^.*\(&#39;],"").sub(%r[&#39;\).*],"").split("&#39;, &#39;")[1]
    end
  end
  # 表示する----------------------------------------------------
  puts title, main_text, picker, picktime, picker_eval, picker_com, pt[2]
  puts arr1, arr2, arr3, arr4, arr5
end

gsub連打してるところは正規表現使ってシンプルにできますが気にしない!
XPATHの使い方とか良く分かってないけど気にしない!
それよかソースが(以前に比べると)断然分かりやすい!
構成が記事部分とコメント部分に完全に分かれてるし、100行以内に収まってるし…。

ちょい解説

すると、newsingの個別記事は記事部分とコメント部分で違うtableになっています。けど今まではopen-uriでアクセスしてソースを1行づつ読み込んでいたので、構成の違う箇所を一度に処理しなければいけませんでした。

しかし!Hpricotを使えば、XPATH(orCSS)を使って特定部分を取り出し、さらにそれをXPATHで解析する事もできるんです。

ところで

神様仏様Hpricot様なのですが、Hpricotって何て読むんですか?今までは「エイチピーリコット」って読んでたけど、Htreeとかの前例から言うと「エイチプリコット」って読むのがいいのかなぁ…。