这不是试图回答所提出的问题,但它会帮助您弄清楚如何处理问题。这是您用于任何抓取或表单填充自动化的一般过程,并且通常只有用于查找特定节点的选择器会发生变化。
使用OpenURI检索页面的实际 HTML;检索 HTML 并将其转储到文件中,以便您可以准确查看发送的内容,而无需浏览器或任何其他代码干扰它:
require 'open-uri'
File.write('test.html', open('https://login.binck.nl/klanten/').read)
如果您想要的字段在 OpenURI 检索时不在表单中,那么 Nokogiri 或 Mechanize 都无法帮助您,因为 Mechanize 构建在 Nokogiri 之上,它用于解析。在这种情况下,它们在 HTML 中,所以Nokogiri和 Mechanize 可以找到它们,你只需要知道如何去做:
<input data-bind="value: $root.username, setFocus:true" type="password"/>
<input data-bind="value: $root.password" type="password"/>
在 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">
所以,字段存在。上面向您展示了如何使用 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层内的服务器,以防止被窥探。因此,像Wireshark和TCPDump这样的普通工具并不能真正提供帮助,因为它们不是 SSL 技术。ssldump可能会将您带到您需要的位置,具体取决于您的操作系统。
在他的回答中,@pguardiario 说使用Fiddler或Charles进入 HTTPS/SSL 层以查看来回传递的实际数据。这些将让您在 Knockout 和 SSL 层有机会玩东西之后看到字段名称。也许他会扩展他的答案以帮助您更多。