Hpricot の練習でプロキシの取得

ProxyForest - プロキシの杜から Rank が A で 2ch の書き込みに使えそうなプロクシを取ってくるスクリプトを書いてみた。

get-proxy.rb

require 'open-uri'
require 'hpricot'

def get_proxy
  ips = []
  ranks = []
  codes = []
  (0..10).each do |n|
    open("http://www.proxyforest.com/proxy.htm?pages=%d" % n) do |f|
      doc = Hpricot(f)
      tr = (doc/"div.blockc/table.list/tbody/tr")[1]
      ips << get_td_ary(tr/"td#address")
      ranks << get_td_ary((tr/"td")[5])
      codes << get_td_ary(tr/"td#write")
    end
  end
  [ips, ranks, codes,].each{|a| a.flatten!}
  ips.zip(ranks, codes).select{|ip, rank, code| /A/ =~ rank and /700|800/ =~ code}.map{|ip, rank| "#{ip} #{rank}"}
end

def get_td_ary(td)
  td.innerHTML.gsub(/\n+/, '').gsub(/\t+/, '').split('<br />').flatten.delete_if{|x| /^:$/ =~ x}
end

puts get_proxy

実行結果

213.131.75.140:8080 A+
208.42.166.23:80 A
160.5.12.10:8080 A
213.172.39.19:80 A
208.42.166.24:80 A
209.161.7.252:80 A
219.136.206.29:80 A-
222.240.212.3:8080 A+
123.224.186.125:15665 A+
88.255.192.42:8080 A+
62.149.95.43:8080 A+
82.151.67.78:8080 A
161.53.125.15:8080 A+
200.174.25.14:8080 A+
200.174.25.14:8080 A+
69.51.81.133:8080 A+
92.65.25.148:8080 A+
142.217.233.139:8080 A+
80.82.118.27:80 A
80.82.118.27:80 A
80.82.118.27:80 A
41.196.19.9:8080 A+
148.243.233.50:80 A
200.43.231.118:6588 A+
213.59.40.243:3128 A+
208.78.145.33:80 A-
202.33.123.65:80 A
213.55.78.154:8080 A+
88.250.229.207:8080 A+
194.78.232.158:3128 A+
200.35.75.93:8080 A+
203.171.239.79:8080 A+
219.136.230.60:8080 A+
58.65.204.154:8080 A+
200.44.122.58:80 A
200.59.239.117:6588 A+


ちょっと加工して Proxy.txt で保存すれば Jane Style で使える。
やるとしたら最後のところを

puts get_proxy.unshift "[Write]"

に直して

$ ruby get-proxy.rb > Proxy.txt

を実行かな。
うんまあどうでもいいですね(´・ω・`)
勢いで書いちゃった。みたいな

追記

id:rubikitch さんから TB をもらった。

複数の配列の並行実行にはArray#zipが便利。あんま知られてないのかな。

Array#zip使おうよ - http://rubikitch.com/に移転しました

zip かー。これを使えばよかったんですね!
早速書き直してみた。

変更前
  ips.flatten!
  ranks.flatten!
  codes.flatten!
  results = []
  ips.size.times do |i|
    results << "#{ips[i]} #{ranks[i]}" if /A/ =~ ranks[i] and /700|800/ =~ codes[i]
  end
  results
変更後
  [ips, ranks, codes,].each{|a| a.flatten!}
  ips.zip(ranks, codes).select{|a| /A/ =~ a[1] and /700|800/ =~ a[2]}.map{|a| "#{a[0]} #{a[1]}"}

zip の他に flatten! 3連続もあれかなと思ったのでそこも直した。
また、results もいらなくなったので消した。
これでどうでしょうか?

追記

each ってこんな使い方もできたんだ…知らなかった - gan2 の Ruby 勉強日記で得た知識を元にさらに少し修正。
これでもっと見やすくなったと思う。

ips.zip(ranks, codes).select{|ip, rank, code| /A/ =~ rank and /700|800/ =~ code}.map{|ip, rank| "#{ip} #{rank}"}