Skip to content

Instantly share code, notes, and snippets.

@59t9
Last active October 30, 2016 11:11
Show Gist options
  • Save 59t9/97f2976f18c22fa59d9651567e2e3430 to your computer and use it in GitHub Desktop.
Save 59t9/97f2976f18c22fa59d9651567e2e3430 to your computer and use it in GitHub Desktop.
TBSラジオクラウド:mp3ダウンロード
require 'net/http'
require 'uri'
require 'nokogiri'
# ruby radiocloud_mp3.rb 番組名
# 公開エピソードに限定して取り扱います。
# 番組名はラジオクラウドの各番組のURLの一部を使います。
# タマフル(https://radiocloud.jp/archive/utamaru)ならば、'utamaru'です。
# 残りの番組も同じ要領です。
# 技術的にはリファラ偽装とサードパーティクッキーの迂回です。
def get_dom(url)
res = Net::HTTP.get(URI(url))
return Nokogiri::HTML.parse(res)
end
def get_dom_ref(url, ref)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.start()
res, = http.get(uri.path, 'Referer' => ref)
cookie = {}
res.get_fields('Set-Cookie').each{|str|
k,v = str[0...str.index(';')].split('=')
cookie[k] = v
}
http.finish()
return [ Nokogiri::HTML.parse(res.body), cookie ]
end
def header_cookie(url, adp)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# http.set_debug_output $stderr
http.start()
req = Net::HTTP::Head.new uri
req['Cookie'] = "AD-P=#{adp}"
res = http.request(req)
http.finish()
return res
end
def get_dom_cookie(url, adp)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# http.set_debug_output $stderr
http.start()
req = Net::HTTP::Get.new uri
req['Cookie'] = "AD-P=#{adp}"
res = http.request(req)
http.finish()
return res.body
end
def get_tune_info(dom)
dom.xpath('//div[@id="contents_open"]//li[@class="contents_box"]').map do |node|
day = node.xpath('dl/dt').inner_text.strip.gsub(/\./ , '_')
name = node.xpath('dl/dd/span').inner_text.strip
filename = day + '_' + name + '.mp3'
tuneid = node.xpath('input[@name="file_url"]/@value').inner_text
[filename, tuneid]
end
end
def get_tune_src(dom)
scr_txt = dom.xpath('//div[@id="content"]/script[@type="text/javascript"]').inner_text
if %r|^.*var source = "(.*)".*$| =~ scr_txt
$1
else
""
end
end
url_base = "https://radiocloud.jp/archive/#{ARGV[0]}/"
uri = URI.parse(url_base)
dom = get_dom(url_base)
arr_tuneid = get_tune_info(dom)
arr_tuneid.map do |filename, tuneid|
url = uri.scheme + ':' + tuneid + '/'
dom, cookie = get_dom_ref(url, url_base)
src = get_tune_src(dom)
if src != ""
url = uri.scheme + ':' + src
adp = cookie['AD-P']
# system("curl '#{url}' -H 'Cookie: AD-P=#{adp}' --compressed -o '#{filename}'")
header_cookie(url,adp).each {|name,value|
p name + " : " + value
}
open(filename,'wb'){|f|
f.write(get_dom_cookie(url, adp))
}
end
end
@59t9
Copy link
Author

59t9 commented Jul 9, 2016

公開分のみです。ひとまず。製品じゃないので動作確認は各自でお願いします。
rubyを使ったのはたんなる主観です。
ところがネイティブでダウンロードがうまくいかなくてcurlを使いました。unix環境というのはcurlが使える環境の意味です。
逆にパラメータを拾うとこだけどうにかしたらあとはcurlとかwgetでいけるでしょう。
「タマフル用」というのもアーカイブ先を決め打ちしてるだけなので、そこ代えれば他の番組もいけると思います。

@59t9
Copy link
Author

59t9 commented Jul 12, 2016

curlを不要にしました。
レスポンスヘッダを取って表示させています。ネイティブでうまくいかなかったのはヘッダに文字化けを作っていたためでした。
ファイル名によっては、一部のpodcastクライアントで読込みができなくなることがあります。

@59t9
Copy link
Author

59t9 commented Jul 26, 2016

「タマフル用」というのを外して番組コードを引数に取るようにしました。
あいかわらずruby実行環境が必要です。プログラミング練習サイトに突っ込んでみましたらNGでした。まあ当然ですわな。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment