以编程方式发布数据

时间:2009-08-24 08:35:15

标签: ruby http

我想以编程方式下载网页的内容,但该页面是作为POST的结果生成的,我似乎无法使其正常工作。

这是页面:http://jp.translink.com.au/mobile/Input.aspx

您可以输入以下值以查看其工作原理:

来自:Coorparoo火车站

至:中央火车站

我使用tcpdump监控流量,并尽可能使用代码重新创建流量。这是测试代码:

http = Net::HTTP.new("jp.translink.com.au", 80)
path = "/mobile/Input.aspx"

# GET request -> so the host can set his cookies
resp, data = http.get(path, nil)
cookie = resp.response['set-cookie']

viewstate = data.match(/"__VIEWSTATE" value="([^"]+)"/)[1]

# POST request -> logging in
data = "__VIEWSTATE=#{viewstate}&FromTextBox=mitchelton+railway+station&FromModeList=stopLandmark&ToTextBox=morayfield+railway+station&ToModeList=stopLandmark&VehicleList%3A1=on&HourList=11&MinuteList=40&NoonList=PM&DateList=0&goButton=Go%21"
headers = {
  'Cookie' => cookie,
  'Referer' => 'http://jp.translink.com.au/mobile/Input.aspx',
  'origin' => 'http://jp.translink.com.au',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'User-Agent' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19',
  'Accept' => 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
  'Accept-Language' => 'en-us',
  'Accept-Encoding' => 'gzip, deflate'
}

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

我收到回复,告诉我重定向到错误页面。有谁知道如何成功地做到这一点?

编辑:谢谢你,很少有人回答我的问题。我下面是我的问题的解决方案:)

require 'mechanize'
agent = WWW::Mechanize.new
initial_page = agent.get('http://jp.translink.com.au/mobile/Input.aspx')
initial_form = initial_page.form('InputForm')
initial_form.FromTextBox = 'Mitchelton Railway Station'
initial_form.radiobuttons_with(:name => 'FromModeList')[1].check
initial_form.ToTextBox = 'Morayfield Railway Station'
initial_form.radiobuttons_with(:name => 'ToModeList')[1].check
initial_form.checkbox_with(:name => 'VehicleList:0').uncheck
initial_form.checkbox_with(:name => 'VehicleList:2').uncheck
go_button = initial_form.buttons[0]
result_page = agent.submit(initial_form, go_button)
puts result_page.body

3 个答案:

答案 0 :(得分:5)

我不会从头开始使用Net库,有很多宝石可以自定义构建来做你想做的事情,看看像mechanize或者{{3}这样的东西}或Webrat

现在任何事情都是可以废弃的,如果你遇到更严重的问题(比如ajax页面内容生成),你可能不得不求助于以编程方式驱动一个浏览器实例--webrat与Selenium集成,这是一个允许你开车的测试工具代码中的浏览器并检查实时浏览器dom。这种方法虽然很慢,但首先尝试机械化,它应该能够做你想做的事。

答案 1 :(得分:1)

在不查看细节的情况下,您的cookie肯定是错误的。你得到了

Set-Cookie: ASP.NET_SessionId=2wo3lv455p2mbfimbmyyqoua; path=/

....然后应该在没有; path=/部分的情况下将其发回,例如:

Cookie: ASP.NET_SessionId=2wo3lv455p2mbfimbmyyqoua

编辑:此外,您的内容长度在哪里?

编辑2 :你的主人在哪里?你不能没有主机,除非网站也只能基于IP地址工作。在这种情况下,实际上it does ......然而:将浏览器标题与您自己的标题进行比较......

编辑3 :您需要对VIEW_STATE的值进行编码。

(请注意,例如,Firefox扩展程序LiveHTTPHeaders可能比tcpdump更容易使用。使用重播选项我可以看到cookie不是必需的,但__VIEW_STATE确实是。也会看到它被编码,并且与GET收到的值不同。)

答案 2 :(得分:0)

选择机械化。如果失败了,那么你可以使用firewatir从Ruby自动化firefox。