在Mechanize请求之间维护cookie

时间:2011-08-12 21:31:49

标签: ruby screen-scraping mechanize

我正在尝试使用Ruby版本的Mechanize从我们正在离开的票证管理系统中提取我的雇主的票据,而不提供API。

问题是,似乎Mechanize没有在post来电和下面显示的get来电之间保留Cookie:

require 'rubygems'
require 'nokogiri'
require 'mechanize'

@agent = Mechanize.new

page = @agent.post('http://<url>.com/user_session', {
                                            'authenticity_token' => '<token>',
                                            'user_session[login]' => '<login>',
                                            'user_session[password]' => '<password>',
                                            'user_session[remember_me]' => '0',
                                            'commit' => 'Login'
})

page = @agent.get 'http://<url>.com/<organization>/<repo-name>/tickets/1'
puts page.title

user_session是网站登录页面POST的URL,我已经确认这确实会让我登录。但是从get调用返回的页面是'哎呀,你“没有登录!”页。

我已经验证了从click调用返回的页面上的post个链接有效,但实际上我无法在没有JavaScript的情况下到达我需要去的地方。当然,我已经使用相同的登录功能在浏览器上成功完成了这项工作。

我做错了什么?

2 个答案:

答案 0 :(得分:13)

好的,这可能会对你有所帮助 - 首先你使用的是什么版本的机械化?您需要确定,如果此问题是由于请求之间的机械化覆盖/清除cookie,或者首先是否错误/未设置cookie。您可以通过在两个请求之间添加puts @agent.cookie_jar.jar来查看存储的内容。

如果是覆盖问题,您可以通过从第一个请求中收集cookie并将其应用到第二个请求来解决它。有很多方法可以做到这一点:

一种方法是只做一个temp_jar = agent.cookie_jar.jar然后只是浏览每个cookie并使用.add方法再次添加它

然而 - 最简单的方法是安装最新的2.1版本的机械化(许多修复),因为您可以非常简单地完成它。 要安装最新的gem install mechanize --pre并确保在此之后删除旧版本的机械gem uninstall mechanize 'some_version',您可以执行以下操作:

require 'rubygems'
require 'nokogiri'
require 'mechanize'

@agent = Mechanize.new

page = @agent.post('http://<url>.com/user_session', {
                                        'authenticity_token' => '<token>',
                                        'user_session[login]' => '<login>',
                                        'user_session[password]' => '<password>',
                                        'user_session[remember_me]' => '0',
                                        'commit' => 'Login'
})
temp_jar = @agent.cookie_jar
#Do whatever you need an use the cookies again in a new session after that
@agent = Mechanize.new
@agent.cookie_jar = temp_jar

page = @agent.get 'http://<url>.com/<organization>/<repo-name>/tickets/1'
puts page.title

BTW文档在这里http://mechanize.rubyforge.org/index.html

答案 1 :(得分:0)

机械化将自动发送从连续请求中的响应获得的cookie。您可以使用相同的代理,而无需续签。

require 'mechanize'

@agent = Mechanize.new
@agent.post(create_sessions_url, params, headers)
@agent.get(ticket_url)

经过mechanize 2.7.6的测试。