13

我正在尝试抓取以下网站:

http://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=0&type=8&season=2011&month=0&season1=2011&ind=0&team=0&rost=0&players=0

如果您单击标题为“导出数据”的表格右上角的小按钮,则会运行一个 javascript 脚本,并且我的浏览器会以 .csv 格式下载该文件。我希望能够编写一个可以自动执行此操作的 PhantomJS 脚本。有任何想法吗?

上面的按钮被编码成 HTML,如下所示:

<a id="LB_cmdCSV" href="javascript:__doPostBack('LB$cmdCSV','')">Export Data</a></div>

我还在 HTML 源代码中找到了这个函数:

<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
    theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>

我对 PhantomJS/Javascript 很陌生,可以在这里使用一些指针。我想我已经找到了自动执行此操作所需的所有信息(如果我错了,请纠正我),但只是不确定从哪里开始编码。谢谢你的帮助。

编辑 - 这是我的脚本现在的样子:

var page = new WebPage();
url = 'http://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=0&type=8&season=2011&month=0&season1=2011&ind=0&team=0&rost=0& players=0';

page.open(encodeURI(url), function (status){
  if (status !== "success") {
    console.log("Unable to access website");
  } else {
      page.evaluate(function() {
        __doPostBack('LB$cmdCSV', '');
      });
    }
  phantom.exit(0);
});
4

4 回答 4

1

对我来说效果很好的是模拟鼠标点击所需的元素。

page.evaluate(function () {
  var btn = document.getElementById('LB_cmdCSV')
  var ev = document.createEvent('MouseEvent')
  ev.initEvent('click', true, true)
  btn.dispatchEvent(ev)
})
于 2015-06-18T10:52:35.800 回答
0

你不能__doPostBack('LeaderBoard1$cmdCSV','');在网页的上下文中运行代码吗?

像这样的东西:

page.evaluate(function() {
  __doPostBack('LeaderBoard1$cmdCSV','');
});

我没有在 PhantomJS 中测试过这段代码,但理论上它应该可以工作,因为从谷歌浏览器的开发者控制台运行 __doPostBack 方法是有效的。如果对在 PhantomJS 中运行 JavaScript 代码有疑问,Google Chrome 的开发者控制台是测试代码的好方法,因为它像 PhantomJS 一样在 WebKit 上运行。我希望这有帮助。

于 2012-01-27T17:29:53.900 回答
-1

这是一个由 ASP 驱动的网站,因此这将比大多数网站更棘手,您将不得不使用 cURL 命令来模拟将整个表单视图状态和事件验证字符串发送回服务器。将数据直接从您拥有的页面中提取出来可能会更容易。

于 2012-02-06T03:03:21.883 回答
-1

我正在使用 Ruby on Rails 和 Watir Webdriver ( https://github.com/watir/watir-webdriver )。

我已经确定该工具在使用客户定义的用户代理使用的“doPostBack”相同浏览器时使用 ASP.NET。当使用 PhantomJS 时,用户代理被标识为“Mozilla/5.0 (Unknown; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) Safari/534.34 PhantomJS/1.9.1”。

因此有必要在访问页面之前更改用户代理客户端。Rails 并做了类似的事情:

HTTP_USER_AGENT    = "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:22.0) Gecko/20100101 Firefox/22.0"
HTTP_DRIVER        = Selenium::WebDriver.for :phantomjs, :desired_capabilities => Selenium::WebDriver::Remote::Capabilities.phantomjs(
  "phantomjs.page.settings.userAgent" => HTTP_USER_AGENT
)
...
browser = Watir::Browser.new HTTP_DRIVER, :http_client => client
于 2013-07-03T15:25:57.143 回答