スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
新しい記事を書く事で広告が消せます。
【Ruby】セッション管理されてるWebページのソースをRubyで取得する
こんばんは、最近すっかり暑くなりましたね。
最近Webサイトをクロールする(サイトの方には許可をもらってます)仕事をよくやっていて、セッションをきちんとみて画面遷移をコントロールしているサイトをクロールするときに勉強になったことをまとめます。
今回も言語はRubyで作ってみました。
当初open-uriを使ってWebページのhtmlソース取得していました。
こんな感じ。
もちろんこれでWebページのhtmlソースを取得することは可能です。むしろシンプルさに関しては個人的には一番好きです。
ただ、この方法だと前述したセッション管理をしてるWebサイトをクロールすることはできません。
たとえばページ送りを実装している部分でかならず1ページを見てから2ページ目以降に遷移させるみたいな制御をかけている場合などです。これは実例としてありました。
実例としてあったのは
いきなり5ページ目のURLにリクエスト→ セッションのCookieをチェック → セッションが不正 → 1ページ目を描画 → セッションキーの発行 → リロード → セッションのCookieをチェック → セッションが妥当 → 5ページ目を描画
こんな流れで処理をしているようでした。
つまりこのようにセッション管理をしているページのhtmlソースを取得したい場合
1. セッションキーを取得するためのリクエスト
2. 1で取得したセッションキーを元に欲しいWebページへリクエスト
このような2回のリクエストが必要になるということです。
そこでこのような処理を書いてみました。
一見さっきも検証した2回のリクエストをきちんと発行しているように見えますが、これだとうまくいかないんです。。
open-uriはコネクションを一回一回のリクエストのたびにコネクションをopen/closeしてしまってるのです。
先ほどの実例を交えたイメージでいうとブラウザで5ページ目を開いて、タブを閉じてまた別のタブで同じURLをみて1ページ目に行ってしまう。こんな感じでしょうか。
net/httpを使えば解決できます。
こんな感じで一つのhttpのコネクション上で2回リクエストを実行すれば正しくhtmlを取得できます。
シンプルに書くならopen-uriを使い、細かい制御を入れるならnet/httpまたはcurlライブラリを使うのが良い感じの使い分けがいいとおもいます。
最近Webサイトをクロールする(サイトの方には許可をもらってます)仕事をよくやっていて、セッションをきちんとみて画面遷移をコントロールしているサイトをクロールするときに勉強になったことをまとめます。
今回も言語はRubyで作ってみました。
当初open-uriを使ってWebページのhtmlソース取得していました。
require 'open-uri'
require 'kconv'
CHROME_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7'
html = open(url, {"User-Agent" => CHROME_USER_AGENT}).read().toutf8
こんな感じ。
もちろんこれでWebページのhtmlソースを取得することは可能です。むしろシンプルさに関しては個人的には一番好きです。
ただ、この方法だと前述したセッション管理をしてるWebサイトをクロールすることはできません。
たとえばページ送りを実装している部分でかならず1ページを見てから2ページ目以降に遷移させるみたいな制御をかけている場合などです。これは実例としてありました。
実例としてあったのは
いきなり5ページ目のURLにリクエスト→ セッションのCookieをチェック → セッションが不正 → 1ページ目を描画 → セッションキーの発行 → リロード → セッションのCookieをチェック → セッションが妥当 → 5ページ目を描画
こんな流れで処理をしているようでした。
つまりこのようにセッション管理をしているページのhtmlソースを取得したい場合
1. セッションキーを取得するためのリクエスト
2. 1で取得したセッションキーを元に欲しいWebページへリクエスト
このような2回のリクエストが必要になるということです。
そこでこのような処理を書いてみました。
require 'open-uri'
require 'kconv'
CHROME_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7'
cookie = open(url, {"User-Agent" => CHROME_USER_AGENT}){|f|f.meta}['set-cookie']
html = open(url, {"User-Agent" => CHROME_USER_AGENT, "Cookie" => cookie}).read().toutf8
一見さっきも検証した2回のリクエストをきちんと発行しているように見えますが、これだとうまくいかないんです。。
open-uriはコネクションを一回一回のリクエストのたびにコネクションをopen/closeしてしまってるのです。
先ほどの実例を交えたイメージでいうとブラウザで5ページ目を開いて、タブを閉じてまた別のタブで同じURLをみて1ページ目に行ってしまう。こんな感じでしょうか。
net/httpを使えば解決できます。
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, 80)
http.start
req = Net::HTTP::Get.new(uri.path + "?" + uri.query)
req['Connection'] = 'Keep-Alive'
response = http.request(req)
cookie_str = ""
response.get_fields('Set-cookie').each {|str|
cookie_str += str
}
req = Net::HTTP::Get.new(uri.path + "?" + uri.query)
req['Connection'] = 'Keep-Alive'
req['Cookie'] = cookie_str
response = http.request(req)
こんな感じで一つのhttpのコネクション上で2回リクエストを実行すれば正しくhtmlを取得できます。
シンプルに書くならopen-uriを使い、細かい制御を入れるならnet/httpまたはcurlライブラリを使うのが良い感じの使い分けがいいとおもいます。
スポンサーサイト
Comment
b6Z230z8
あの…
私、すごい人見知りなんです…
だから、こういうサイト使わないと、男の人と知り合えなくて…
こんな女じゃ、興味湧きませんよね…すみません…
http://rolih5Rl.m5wt.mobi/rolih5Rl/