【问题标题】:Scraping Javascript generated data抓取 Javascript 生成的数据
【发布时间】:2013-03-11 02:45:20
【问题描述】:

我正在与世界银行合作开展一个项目,分析他们的采购流程。

世界银行为其每个项目维护网站,其中包含已签发的相关合同的链接和数据 (example)。采购选项卡下提供了与合同相关的数据。

我希望能够从该站点提取项目的合同信息,但是链接和相关数据是使用嵌入式 Javascript 生成的,并且显示合同授予和其他数据的页面的 URL 似乎没有跟随一个可辨别的模式 (example)。

有什么方法可以通过 R 抓取第一个示例中的浏览器渲染数据?

【问题讨论】:

  • 对不起,我有点困惑。你如何从第一个链接共享到第二个链接?而且,我假设它是您要抓取的第二个链接上的数据,对吗?我不清楚您要在这里提出的实际问题。
  • 要从项目页面(第一个链接)获得合同授予(第二个链接),您需要转到采购选项卡,然后转到合同授予子菜单。合同授予示例是表中的第一个条目。我已经有一些东西可以在第二个链接上抓取数据;我正在寻找的是一种从第一个链接中找到第二个链接的方法(这是 Javascript 生成的位)。

标签: r scrape


【解决方案1】:

主页面调用一个javascript函数

javascript:callTabContent('p','P090644','','en','procurement','procurementId');

这里主要是项目 id P090644。这与所需的语言en 一起作为参数传递给http://www.worldbank.org/p2e/procurement.html 的表单。

此表单调用可以使用 url http://www.worldbank.org/p2e/procurement.html?lang=en&projId=P090644 复制。

提取相关项目描述url的代码如下:

projID<-"P090644"
projDetails<-paste0("http://www.worldbank.org/p2e/procurement.html?lang=en&projId=",projID)

require(XML)

pdData<-htmlParse(projDetails)
pdDescribtions<-xpathSApply(pdData,'//*/table[@id="contractawards"]//*/@href')

#> pdDescribtions
                                                                href 
#"http://search.worldbank.org/wcontractawards/procdetails/OP00005718" 
                                                                href 
#"http://search.worldbank.org/wcontractawards/procdetails/OP00005702" 
                                                                href 
#"http://search.worldbank.org/wcontractawards/procdetails/OP00005709" 
                                                                href 
#"http://search.worldbank.org/wcontractawards/procdetails/OP00005715" 

应该注意的是,提供的 excel 链接也可能对您有用。它们可能包含您打算从描述链接中删除的数据

procNotice<-paste0("http://search.worldbank.org/wprocnotices/projectdetails/",projID,".xls")
conAward<-paste0("http://search.worldbank.org/wcontractawards/projectdetails/",projID,".xls")
conData<-paste0("http://search.worldbank.org/wcontractdata/projectdetails/",projID,".xls")

require(gdata)

pnData<-read.xls(procNotice)
caData<-read.xls(conAward)
cdData<-read.xls(conData)

更新:

要查找发布的内容,我们可以检查调用 javascript 函数时发生的情况。使用 Firebug 或类似的东西,我们拦截了开始的请求标头:

POST /p2e/procurement.html HTTP/1.1
Host: www.worldbank.org

并且有参数:

lang=en
projId=P090644

或者,我们可以检查 http://siteresources.worldbank.org/cached/extapps/cver116/p2e/js/script.js 的 javascript 并查看函数 callTabContent

function callTabContent(tabparam, projIdParam, contextPath, langCd, htmlId, anchorTagId) {
    if (tabparam == 'n' || tabparam == 'h') {
        $.ajax( {
            type : "POST",
            url : contextPath + "/p2e/"+htmlId+".html",
            data : "projId=" + projIdParam + "&lang=" + langCd,
            success : function(msg) {
                if(tabparam=="n"){
                    $("#newsfeed").replaceWith(msg);
                } else{
                    $("#cycle").replaceWith(msg);
                }
                stickNotes();
            }
        });
    } else {
        $.ajax( {
            type : "POST",
            url : contextPath + "/p2e/"+htmlId+".html",
            data : "projId=" + projIdParam + "&lang=" + langCd,
            success : function(msg) {
                $("#tabContent").replaceWith(msg);
                $('#map_container').hide();
                changeAlternateColors();
                $("#tab_menu a").removeClass("selected");
                $('#'+anchorTagId).addClass("selected");                
                stickNotes();
            }
        });
    }
}

检查函数的内容,我们可以看到它只是将相关参数发布到表单然后更新网页。

【讨论】:

  • 您能否编辑您的答案以解释您如何想出如何在 HTML 中复制表单?我可以看到这在未来很有用。
  • 你太棒了!!非常感谢!
【解决方案2】:

我不确定我是否了解您问题的所有细节。 但我可以肯定的是,casperJS 非常适用于 javascript 生成的内容。

您可以在这里查看:http://casperjs.org/

它是用 Javascript 编写的,并且在我提供的链接上很好地记录了许多有用的功能。

我最近自己将它用于个人项目,只需几行代码即可轻松设置。

试一试! 希望,这有帮助..

【讨论】:

    猜你喜欢
    • 2012-09-19
    • 1970-01-01
    • 2012-04-20
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多