Mechanize找不到合适的字段

时间:2013-11-04 15:09:55

标签: ruby mechanize

我正在尝试登录以下网站:https://login.binck.nl/klanten/

Mechanize只能找到字段__RequestVerificationToken,但不能找到usernamepassword字段。我用这段代码来发现字段:

require 'rubygems'
require 'mechanize'

agent = Mechanize.new

page = agent.get('https://login.binck.nl/klanten/')
form = page.forms.first
form.fields.each { |f| puts "#{f.name} : #{f.value}" }  

似乎usernamepassword字段没有名称,网站正在使用Knockout.js,所以可能这就是它无法正常工作的原因。即使添加usernamepassword字段,网站仍然不允许我登录

form.add_field!('username', 'MY_USERNAME')
form.add_field!('password', 'MY_PASSWORD')

page = agent.submit form

puts page.body

有没有人有解决方案如何自动登录本网站?

2 个答案:

答案 0 :(得分:1)

这不是试图回答问题,但它会帮助您弄清楚如何处理问题。这是您用于任何抓取或表单填充自动化的一般过程,并且通常只有用于查找特定节点的选择器会发生变化。

  1. 使用OpenURI检索页面的实际HTML;检索HTML并将其转储到文件中,这样您就可以看到完全发送的内容,而无需浏览器或任何其他代码搞乱它:

    require 'open-uri'
    
    File.write('test.html', open('https://login.binck.nl/klanten/').read)
    

    如果您想要的字段在OpenURI检索时不在表单中,那么Nokogiri或Mechanize都无法帮助您,因为Mechanize构建在Nokogiri之上,它用于解析。在这种情况下,他们在HTML中 ARE ,所以Nokogiri和Mechanize可以找到它们,你只需要知道如何去做:

    <input data-bind="value: $root.username, setFocus:true" type="password"/>
    <input data-bind="value: $root.password" type="password"/>
    
  2. 在Nokogiri中,您可以通过多种不同方式找到特定节点。它支持CSS和XPath选择器,可以让您查看节点的属性/参数。有时节点没有任何特别区别的东西,所以你看围绕它的地标。在这种情况下,周围class="form_line"标记中的<div>是您搜索的基础,为了添加定义,我们可以添加周围的<div class="body">。或者,<input>代码也很有用,因为我们可以查看type参数。这是一个CSS选择器,它将在该块中选择“密码”输入标签:

    require 'nokogiri'
    require 'open-uri'
    
    doc = Nokogiri::HTML(open('https://login.binck.nl/klanten/'))
    inputs = doc.css('input[@type="password"]')
    

    如果我在IRB中运行该代码,我可以查看返回的节点:

    >> puts doc.css('input[@type="password"]').map(&:to_html)
    

    见:

    <input data-bind="value: $root.username, setFocus:true" type="password">
    <input data-bind="value: $root.password" type="password">
    
  3. 因此,字段存在。上面将向您展示如何使用Nokogiri指向它们,Nokogiri是Mechanize的核心。 Mechanize将解析的Nokogiri DOM暴露给您。你如何做到这一点并使用它留给你锻炼。

    输入代码没有或不需要name参数,因为该网页正在使用Knockout.js来处理字段:

    <script type="text/javascript" src="/klanten/Scripts/knockout-2.2.0.js" ></script>
    

    (使用它的教程,特别是从“3/5”页面开始,看看它在你试图解析的页面中做了什么。)

    上面的内容开始分崩离析......

    Mechanize不能将值填充到字段中并提交它们,因为Knockout必须完成它的工作,它需要一个JavaScript解释器。您将不得不尝试使用WATIR驱动的浏览器来允许它处理JavaScript,这将让Knockout运行,因此它可以实现它的魔力并提交数据。 (如果它不是HTTPS连接,您可以使用WireShark嗅探线路以查找正在发送的值,但这只是解决方案的一部分,您还必须捕获cookie和会话信息。)

    分开JavaScript也会使任务变得更加困难,因为它可以如此动态。代码可以在页面加载时加载,也可以在页面加载后很好地加载,基于发生的某些触发,例如单击“提交”按钮,因此代码根本不可见。你必须嗅探电线或花时间拆解他们的代码。无论哪种方式,工作都变得更加困难。

    嗅探连接的问题是,HTTPS将正常的HTTP流量从浏览器包装到SSL层内的服务器,以防止它被窥探。因此,WiresharkTCPDump等常规工具无法提供真正的帮助,因为它们不是SSL-saavy。根据您的操作系统,ssldump可能会让您到达您需要的位置。

    在他的回答中,@ pguardiario表示要使用FiddlerCharles进入HTTPS / SSL层,以查看来回传递的实际数据。那些会让你看到Knockout之后的字段名称和SSL层有机会玩的东西。也许他会扩展他的答案,以帮助你更多。

答案 1 :(得分:1)

一般情况下你会这样做:

form['username'] = 'foo'
form['password'] = 'bar'

但是,这些不是正确的字段名称。要发现正确的字段名称,您希望通过ssl(mitm)代理(如fiddler或charles)代理您的浏览器请求,并查看它发送的内容。

看起来您还需要更改form.method