修订(澄清问题)
我已经花了几天时间试图弄清楚如何从facebook游戏中获取特定信息;然而,我遇到了一堵又一堵砖墙。据我所知,主要问题如下。我可以使用Chrome的inspect元素工具手动找到我需要的html——它位于iframe中。然而,当我尝试刮取该iframe时,它是空的(除了属性):
<iframe id="game_frame" name="game_frame" src="" scrolling="no" ...></iframe>
如果我使用浏览器"查看页面源代码"工具,这与我看到的输出相同。我不明白为什么我看不到iframe中的数据。答案并不是AJAX随后添加了它。(我知道这一点,既因为"查看页面源代码"可以读取Ajax添加的数据,也因为我有b/c,所以我一直等到看到数据页面后才抓取它,但它仍然不在那里)。
这是因为脸书的反刮屏吗?如果是的话,有办法解决吗?或者我只是错过了什么。我用ruby编程,我尝试过nokogiri,然后机械化,然后水豚,但都没有成功。
我不知道这是否有什么不同,但在我看来,iframe是使用iframe的"game_frame"引用来获取数据的,该引用显然指的是文档早期出现的这段html:
<form id="hidden_login_form_1331840407" action="" method="POST" target="game_frame">
<input type="hidden" name="signed_request" autocomplete="off" value="v6kIAsKTZa...">
...
</form>
原始问题
我写了一个ruby程序,使用nokogiri从facebook游戏的HTML中抓取数据。目前,我通过使用chrome的"inspect元素"工具获得HTML,并将其保存到一个文件中,然后从那里解析它。然而,我真的希望能够从ruby中访问这些信息。例如,我会将页面名称"www.gamename.com/…?id=12345"传递给程序,它会登录到facebook,转到该页面并收集数据。目前,如果我尝试,它不起作用,因为我会被重定向到facebook的登录页面。如何通过登录屏幕访问我需要的页面?
我想使用我已经编写的nokogiri代码来完成这项工作;然而,如果必须的话,我可以用其他东西重写它。目前,该程序是一个独立的程序,而不是rails程序,但我可以改变这一点。我看到了一些信息,这些信息可能会为我指明Omniauth的方向,但我不确定这是我想要的,而且它看起来也非常复杂。我希望有一个更简单的解决方案。
感谢
我可以推荐水豚webkit来完成这类任务。它在后台使用QtWebkit,并理解Javascript:
require 'capybara-webkit'
require 'capybara/dsl'
require 'nokogiri'
include Capybara::DSL
Capybara.current_driver = :webkit
# login
visit("https://www.facebook.com")
find("#email").set("user")
find("#pass").set("password")
find("#loginbutton//input").click
# navigate to the JS-generated page
visit("www.gamename.com/...?id=12345")
# parse HTML
doc = Nokogiri::HTML.parse(body)
最简单的方法是使用机械化:
require 'mechanize'
@agent = Mechanize.new{|a| a.user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'}
page = @agent.get 'http://www.facebook.com/'
form = page.forms[0]
form['email'], form['pass'] = 'me@myemail.com', 'foobar'
form.submit
# now you're logged in and a request like this:
doc = @agent.get('http://www.facebook.com/').parser
# gives you a logged in Nokogiri::HTML::Document like you're used to