2012-01-30 70 views
1

我正在編寫一個ruby應用程序,可以代表用戶向遠程博客發表評論。我的問題是,我有在控制器的POST方法使用相同的頁面,保持會話活着&填寫驗證碼:通過請求邊界保持機械化頁面

應用程序/控制器/ comment_controller.rb

require 'mechanize' 
class CommentController < ApplicationController 
    def new 
     agent = Mechanize.new 
     @page = agent.get('http://blog.example.com') 
     @captcha_src = @page.search("//div[@id='recaptcha_image']").search("//img")[1].attribute("src") 
     #etc. 
    end 

    def post_comment 
     # insert captcha, username, password + text into the form 
     agent.submit(@page.form[0], @page.form[0].buttons.submitbutton) # Problem: page instance variable doesn't exist anymore 
    end 
end 

我已經嘗試在Rails.cache中保存頁面實例變量,但不能將機械化頁面編組爲字符串。

+0

這是一個軌道控制器嗎?爲什麼你會認爲@page會在請求之間持續存在?或代理人的事情?有一個'新'方法似乎是一個好主意?我認爲你在這裏錯過了對ruby和/或rails的基本理解。 – pguardiario 2012-01-30 16:16:53

+0

@pguardiario:我不認爲'@page'在請求之間持續存在,請參閱agent.submit行註釋,這就是問題的核心。新方法是軌道生成(腳手架)。 – wintersolutions 2012-01-30 18:07:58

回答

0

我寫了一個工作解決方案。它將隱藏變量和cookie保存在base64編碼的字符串中,這些字符串在隱藏字段中的請求之間傳輸。下面繼承代碼:

require 'mechanize' 
require 'stringio' 
require 'base64' 

class MechanizeWrapper 
    attr_reader :page, :agent 

    def initialize(url, useproxy = true) 
    @agent = Mechanize.new 
    @page = @agent.get(url) 
    end 

    def get_state() 
    hidden_fields = {} 
    cookie_jar = StringIO.new 

    @page.search("//input[@type='hidden']").each do |hidden| 
     hidden_fields[hidden.path]=hidden.attribute('value').to_s 
    end 

    @agent.cookie_jar.dump_cookiestxt(cookie_jar); 

    state = {:hidden_fields => hidden_fields.inspect, :cookie_jar => cookie_jar.string} 
    Base64.encode64(state.inspect) 
    end 

    def put_state(state_enc) 
    state = eval(Base64.decode64(state_enc)) 
    eval(state[:hidden_fields]).each do |path,value| 
     @page.search(path).first['value'] = value 
    end  

    cookie_jar = StringIO.new(state[:cookie_jar]) 
    @agent.cookie_jar.load_cookiestxt(cookie_jar) 
    end 
end