如何在ruby net / http中实现cookie支持?

我想通过net / http来添加cookie支持ruby类来浏览网页。 脚本结束后,Cookie必须存储在文件中才能存活。 当然,我可以阅读规范并编写某种处理程序,使用一些cookie.txt格式等,但似乎意味着重新发明轮子。 有没有更好的方法来完成这项任务? 也许某种酷狗jar子类照顾cookies?

采取从DZone片段

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 

更新

 #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 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值分别存储的响应头的内部表示forms,然后从这些string的第一个分号后面删除所有内容并将它们连接在一起。 这是有用的代码

 r = http.get(path) cookie = {'Cookie'=>r.to_hash['set-cookie'].collect{|ea|ea[/^.*?;/]}.join} r = http.get(next_path,cookie) 

使用http-cookie ,它实现RFC兼容的parsing和渲染,再加上一个jar。

一个粗略的例子,发生在login后redirect:

 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的情况下(发生在我身上)工作,所以如果您想要处理多个特定的案例。

我已经使用了“遏制”和“机械化”来进行类似的项目。 只需启用cookie支持,并将cookie保存到临时cookiejar …如果您使用net / http或没有cookie支持的包内置,您将需要编写自己的cookie处理。

您可以使用标题发送接收cookie。

您可以将标题存储在任何持久性框架中。 无论是某种数据库还是文件。