修订(澄清问题)
我已经花了几天时间试图弄清楚如何从Facebook游戏中抓取特定信息;然而,我在砖墙后遇到了砖墙。尽我所知,主要问题如下。我可以使用Chrome的inspect元素工具手动查找我需要的html - 它显示在iframe中。但是,当我尝试刮取那个iframe时,它是空的(属性除外):
<iframe id="game_frame" name="game_frame" src="" scrolling="no" ...></iframe>
如果我使用浏览器“查看页面源”工具,这与我看到的输出相同。 我不明白为什么我看不到iframe中的数据。答案并非后来由AJAX添加。 (我知道这两者都是因为“查看页面源代码”可以读取由Ajax添加的数据,也因为我已经等待,直到我可以在抓取之前看到数据页面并且它仍然不在那里之后。
这是因为facebook的反屏幕抓取而发生的,如果是这样的话还有办法吗?或者我只是遗漏了一些东西。我用红宝石编程,我尝试过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的“检查元素”工具获取HTML,并将其保存到文件并从那里解析它。但是,我真的希望能够从ruby中访问信息。例如,我将程序的页面名称“www.gamename.com/...?id=12345”传递给它,它将登录到facebook,转到该页面并刮取数据。目前,如果我尝试,它不起作用,因为我被重定向到Facebook的登录页面。如何通过登录界面访问我需要的页面?
我想使用我已经写过的nokogiri代码来做这件事;但是,如果我必须,我可以使用其他东西重写它。目前,该程序是一个独立的程序 - 而不是一个rails程序 - 但我可以改变它。我看到一些可能指向Omniauth方向的信息,但我不确定这是我在寻找什么,而且看起来也很复杂。我希望有一个更简单的解决方案。
由于
答案 0 :(得分:6)
我可以为这类任务推荐capybara-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)
答案 1 :(得分:4)
最简单的方法是使用机械化:
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