Net/httpを利用してWebを閲覧するRubyクラスにcookieサポートを追加したいと思います。スクリプトの終了後も存続するには、Cookieをファイルに保存する必要があります。もちろん、仕様を読んで何らかのハンドラーを作成し、cookie.txt形式などを使用することもできますが、それは車輪の再発明を意味するようです。このタスクを達成するためのより良い方法はありますか?たぶん、クッキーの世話をするクーリージャークラスのようなものでしょうか?
DZone Snippets から取得
http = Net::HTTP.new('profil.wp.pl', 443)
http.use_ssl = true
path = '/login.html'
# GET request -> so the Host can set his cookies
resp, data = http.get(path, nil)
cookie = resp.response['set-cookie'].split('; ')[0]
# POST request -> logging in
data = 'serwis=wp.pl&url=profil.html&tryLogin=1&countTest=1&logowaniessl=1&login_username=blah&login_password=blah'
headers = {
'Cookie' => cookie,
'Referer' => 'http://profil.wp.pl/login.html',
'Content-Type' => 'application/x-www-form-urlencoded'
}
resp, data = http.post(path, data, headers)
# Output on the screen -> we should get either a 302 redirect (after a successful login) or an error page
puts 'Code = ' + resp.code
puts 'Message = ' + resp.message
resp.each {|key, val| puts key + ' = ' + val}
puts data
update
#To save the cookies, you can use PStore
cookies = PStore.new("cookies.pstore")
# Save the cookie
cookies.transaction do
cookies[:some_identifier] = cookie
end
# Retrieve the cookie back
cookies.transaction do
cookie = cookies[:some_identifier]
end
サーバーが戻って複数のCookieを予期している場合、受け入れられた回答は機能しません。これは、たとえば、サーバーがFedAuth [n] Cookieのセットを返す場合に発生する可能性があります。これが影響する場合は、代わりに次の行に沿って何かを使用することを検討してください。
http = Net::HTTP.new('https://example.com', 443)
http.use_ssl = true
path1 = '/index.html'
path2 = '/index2.html'
# make a request to get the server's cookies
response = http.get(path)
if (response.code == '200')
all_cookies = response.get_fields('set-cookie')
cookies_array = Array.new
all_cookies.each { | cookie |
cookies_array.Push(cookie.split('; ')[0])
}
cookies = cookies_array.join('; ')
# now make a request using the cookies
response = http.get(path2, { 'Cookie' => cookies })
end
受け入れられた答えは機能しません。複数のset-cookie値が個別に格納されている応答ヘッダーの内部表現にアクセスし、これらの文字列から最初のセミコロン以降をすべて削除して、それらを結合する必要があります。動作するコードは次のとおりです
r = http.get(path)
cookie = {'Cookie'=>r.to_hash['set-cookie'].collect{|ea|ea[/^.*?;/]}.join}
r = http.get(next_path,cookie)
http-cookie を使用します。これは、RFC準拠の解析とレンダリング、およびjarを実装します。
ログイン後のリダイレクトをたまたま辿る粗雑な例:
require 'uri'
require 'net/http'
require 'http-cookie'
uri = URI('...')
jar = HTTP::CookieJar.new
Net::HTTP.start(uri.Host, uri.port, use_ssl: uri.scheme == 'https') do |http|
req = Net::HTTP::Post.new uri
req.form_data = { ... }
res = http.request req
res.get_fields('Set-Cookie').each do |value|
jar.parse(value, req.uri)
end
fail unless res.code == '302'
req = Net::HTTP::Get.new(uri + res['Location'])
req['Cookie'] = HTTP::Cookie.cookie_value(jar.cookies(uri))
res = http.request req
end
どうしてですか?上記の答えは信じられないほど不十分であり、フラットアウトは多くのRFC準拠のシナリオでは機能しないため(私に起こりました)、複数の特定のケースを処理したい場合、必要なものだけを実装する非常にlibに依存することは無限に堅牢です。
同様のプロジェクトにCurbとMechanizeを使用しました。 Cookieのサポートを有効にして、一時的なCookiejarにCookieを保存するだけです。net/ httpまたはCookieのサポートが組み込まれていないパッケージを使用している場合は、独自のCookie処理を記述する必要があります。
ヘッダーを使用して受信Cookieを送信できます。
ヘッダーは永続フレームワークに保存できます。何らかのデータベースか、ファイルか。