如何使用JSON列出包含链接的维基百科页面标题?

时间:2015-07-12 09:29:26

标签: javascript json wikipedia-api

这是我目前的代码。它完美地列出了页面标题,但链接都返回'undefined'。

function func(json) {
  var e = document.getElementById('wiki');
  var i;
  for (i=0; i < json.query.allpages.length; i++) {
    e.innerHTML += i + ": " + '<a href="' + "http://en.wikipedia.org/wiki/" +  json.query.link+ '">' +  json.query.allpages[i].title + '</a>' + "<br />";
  }
}

function getFromWikipedia() {
  var txt = document.getElementById('txt');
  var e = document.getElementById('wiki');
  var o = document.createElement("script");
      o.setAttribute("src", "http://en.wikipedia.org/w/api.php?action=query&list=allpages&format=json&apfrom="+txt.value+"&generator=alllinks&callback=func");
  e.appendChild(o);
}

将“&amp; prop = links”和/或“&amp; generator = alllinks”添加到网址似乎不会影响结果。

我想知道我应该在这部分中包含什么:

'<a href="' + json.query.link+ '">'

以列出页面标题及其各自的链接。 我试过“json.query.allpages [i] .pageID”和“json.query.alllinks”,但它一直没有用。

修改 放弃查找URL并转而使用pageid方法。

解决了这个问题:

e.innerHTML += i + ": " + '<a href="'+ "http://en.wikipedia.org/wiki/?curid="+  json.query.allpages[i].pageid + '">' +  json.query.allpages[i].title + '</a>' + "<br />";

2 个答案:

答案 0 :(得分:2)

您可以使用pageid直接创建链接:

function func(json) {
  var e = document.getElementById('wiki');
  var i;
  for (i=0; i < json.query.allpages.length; i++) {
    e.innerHTML += i + ": " + '<a href="' + "http://en.wikipedia.org/?curid=" +  json.query.allpages[i].pageid+ '">' +  json.query.allpages[i].title + '</a>' + "<br />";
  }
}

答案 1 :(得分:1)

同一查询中同时包含list=generator=的事实告诉我,您并不完全了解generators在MediaWiki API中的工作方式。

基本上,生成器是一种使用list作为检索properties的页面源的方法。使用生成器作为另一个列表查询的输入确实 没有任何意义。也就是说,您通常将generator=prop=一起使用,list=一起使用。 MediaWiki(貌似)允许这样做的唯一原因是:

  1. 您可以使用页面列表(或生成器)进行查询,但不能使用prop=参数like this进行查询。如果这样做,您将获得页面的最小默认属性集(标题,名称空间和页面ID)。

  2. 您还可以将属性查询和列表查询合并到一个请求like this中。您将获得两个查询的结果,合并到相同的JSON / XML /等。输出,但它们将完全分开。 (你也可以这样做multiple simultaneous list queries。)

  3. 因此,当您将generator=list=查询组合在一起时,您将获得列表的常规输出和生成器匹配的页面的最小属性集。除了作为相同API响应的一部分外,两个输出不会以任何实际方式连接。

    无论如何,您想知道如何使用链接获取所有维基百科页面的标题和URL。好吧,正如schudel在回答中所说,要获取某些页面的网址,您需要prop=info inprop=url;要在所有链接的页面上运行此查询,您可以使用generator=alllinks。因此,您最终得到:

    请注意,这会提供有关链接的所有网页的信息。要在包含链接的所有网页上运行查询,您需要添加参数galunique=true

    (是的,this is documented,虽然不尽可能清楚。)

    显然,链接目标将包含大量缺失页面。链接来源似乎也包含一个空标题的缺失页面的事实可能是由于维基百科的链接数据库中的错误记录。这可以通过重建(冗余)链接表来修复,但是,考虑到维基百科的大小,这将花费相当多的时间(在此期间,可能必须将站点锁定为只读模式以避免进一步的不一致)

    要在JavaScript中处理此数据,您可以执行以下操作:

    var apiURL = 'https://en.wikipedia.org/w/api.php?format=json&action=query&prop=info&inprop=url&generator=alllinks&callback=myCallback';
    
    function myCallback(json) {
      var e = document.getElementById('wiki');
      for (var id in json.query.pages) {
        var page = json.query.pages[id];
        if (typeof(page.missing) !== 'undefined') continue;
        e.innerHTML += 
          id + ': <a href="' + escapeHTML(page.fullurl) + '">' + escapeHTML(page.title) + '</a><br />';
      }
      // handle query continuations:
      if (json.continue) {
        var continueURL = apiURL;
        for (var attr in json.continue) {
          continueURL += '&' + attr + '=' + encodeURIComponent(json.continue[attr]);
        }
        doAjaxRequest(continueURL);
    }
    
    doAjaxRequest(apiURL + '&continue=');
    

    请注意,我还提供了处理query continuations的基本机制,因为在使用alllinks时您肯定需要处理这些机制。实现辅助函数escapeHTML()doAjaxRequest()是一项练习。另请注意,我实际上没有测试过这段代码;我认为没关系,但可能存在我错过的错误。它还会产生一个非常长的列表,并且可能会使浏览器变慢,因为维基百科有一个很多的页面。对于实际应用程序,您可能希望引入某种按需加载方案(例如,当用户向下滚动到当前列表的末尾时仅加载更多结果)。