使用JavaScript回发来刮取HTML

时间:2012-06-26 22:36:51

标签: php html web-scraping

我正在尝试抓取一些HTML(经作者许可)。我使用的是PHP库suggested here,它运行良好,直到我遇到一个如下所示的链接:

<a href="javascript:__doPostBack('dgItem$_ctl2$_ctl0','')">

我相信是一些asp.net的东西。当我点击它时,它不会改变URL,它只会将一些新内容加载到页面中,我也想抓一下。

我怎样才能解决这个问题?

我想我需要模拟点击,但在处理原始HTML时我不能这样做,我需要某种浏览器/ JS解释器,不是吗?

这个任务有更适合的库吗?我不仅限于PHP,但它更受欢迎。

2 个答案:

答案 0 :(得分:7)

__doPostBack()确实是ASP.NET的事情。这是函数的作用:

var theForm = document.forms['FORMNAME'];
if (!theForm) {
    theForm = document.FORMNAME;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}

基本上,它将两个隐藏字段(__EVENTTARGET__EVENTARGUMENT)的值设置为参数的相应值。然后它提交表格。

如果您愿意,可以继续使用PHP HTML解析器来完成工作,但是当您遇到其中一个__doPostBack()链接时,您必须手动制作POST请求。从高层次来看,你会看到类似的东西:

  1. 获取当前的表单值。您可能需要循环遍历每个input元素等,并将值添加到数组中。如果页面上没有文本框,复选框等,则应该只保留默认情况下.NET嵌入的隐藏字段(例如__VIEWSTATE__EVENTVALIDATION等)。
  2. 解析传递给doPostBack()的值并覆盖__EVENTTARGET__EVENTARGUMENT的现有值。
  3. 制作您的POST请求。我不确定你所看到的库是什么(如果有的话)提供这种方式,但是从PHP执行此操作的一种流行方式是通过cURL扩展。有关示例,请参阅http://davidwalsh.name/execute-http-post-php-curl
  4. 获取HTML结果并照常解析库。
  5. 或者,如果您总是向同一页面发出相同的请求,则可以跳过解析表单的一些步骤,然后直接跳转到制作POST请求。

    这不会有很多乐趣,但它适用于这种情况。如果你需要处理涉及JS的更复杂的案例,或者你只是想以不同的方式处理它,那么(如你所提到的)库基本上可以驱动浏览器并为你处理这些事情。首先想到的两个是:

    还有其他选项,但我不知道任何可以快速轻松地集成到现有PHP脚本中的选项。

答案 1 :(得分:1)

我最终使用Python和Selenium Firefox Web驱动程序。由于我使用真正的浏览器,我可以做FF所能做的一切。