【问题标题】:Mechanize can't find right fields机械化找不到正确的字段
【发布时间】:2013-11-05 21:47:55
【问题描述】:

我正在尝试登录以下网站: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

有没有人知道如何自动登录这个网站?

【问题讨论】:

  • Binck.nl 是一个银行网站。它可能有一些安全限制来防止机器人/脚本登录。

标签: ruby mechanize


【解决方案1】:

通常你会这样做:

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

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

看来您也需要更改 form.method

【讨论】:

    【解决方案2】:

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

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

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

      如果您想要的字段在 OpenURI 检索时不在表单中,那么 Nokogiri 或 Mechanize 都无法帮助您,因为 Mechanize 构建在 Nokogiri 之上,它用于解析。在这种情况下,它们 ARE 在 HTML 中,所以 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" 周围的 &lt;div&gt; 标记是您搜索的基础,为了添加定义,我们可以添加周围的 &lt;div class="body"&gt;。或者,&lt;input&gt; 标记也很有用,因为我们可以查看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">
      

    因此,这些字段存在。上面向您展示了如何使用 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 层有机会玩东西之后看到字段名称。也许他会扩展他的答案来帮助你更多。

    【讨论】:

    • 我不明白你为什么要使用 open-uri 来回答机械化问题。
    • 因为使用 Mechanize 检索 HTML 只是为了将其转储到磁盘以确认标签是静态的,这是浪费时间。你读过我写的吗?这是为了帮助 OP 了解如何确定 Nokogiri 或 Mechanize 是否是合适的工具。
    • 不,我们已经知道机械化是一个合适的工具。 Open-uri 是浪费时间,因为它是一个死胡同。您对输入标签也有误,它们没有名称,因此它们不是表单字段。
    • Wireshark 无法“嗅探”https 流量。为此,您需要一个 mitm 代理。您经常提出有见地的帖子,但是这个答案确实是完全的损失。这里没有什么有用的,只是很多指向错误的方向。
    • 你是对的,这是一个 HTTPS 连接,Wireshark 无法提供帮助,因为 SSL 管道隐藏了线路上的内容。这对于正常的未加密 HTTP 连接很有用。同样,这个答案是为了让用户思考如何处理这些东西。你可能有不同的方向;你有权获得它。 OP是需要帮助的人,而您似乎忽略了这一点;更详细地解释你将如何做到这一点,并帮助而不是攻击其他答案。
    猜你喜欢
    • 1970-01-01
    • 2017-01-19
    • 2015-09-13
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多