如何使用 JSON 列出带有链接的维基百科页面标题?
How to list Wikipedia page titles with links using JSON?
这是我当前的代码。它完美地列出了页面标题,但链接都是 return '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);
}
将“&prop=links”and/or“&generator=alllinks”附加到 URL 似乎不会影响结果。
我想知道这部分应该包括什么:
'<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 />";
您可以直接使用页面 ID 创建 link:
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 />";
}
}
在同一个查询中您同时拥有 list=
和 generator=
这一事实向我表明您并不完全理解 generators 在 MediaWiki 中的工作方式 API.
基本上,生成器是一种使用 list as the source of pages to retrieve properties 的方式。 not 使用生成器作为另一个列表查询的输入没有任何意义。也就是说,您通常将 generator=
与 prop=
一起使用, 而不是 与 list=
。 MediaWiki(表面上)允许这样做的唯一原因是:
您可以使用页面列表(或生成器)进行查询,但没有 prop=
参数,like this。如果这样做,您只会获得页面的最小默认属性集(标题、命名空间和页面 ID)。
您还可以将属性查询和列表查询合并到一个请求中,like this. You'll just get the results for both queries, merged into the same JSON/XML/etc. output, but they'll be otherwise completely separate. (You can also make multiple simultaneous list queries 这样。)
因此,当您将 generator=
与 list=
查询结合使用时,您将获得列表的常规输出和生成器匹配的页面的最小属性集。这两个输出不会以任何实际方式连接,除非是相同 API 响应的一部分。
无论如何,您想知道如何获取所有带有 links 的维基百科页面的标题和 URL。好吧,正如 schudel 在他们的回答中指出的那样,要获取某些页面的 URL,您需要 prop=info
和 inprop=url
;对于 运行 所有 linked 页面上的此查询,您可以使用 generator=alllinks
。因此,您最终得到:
请注意,这提供了所有包含 links from 的页面的信息。要运行查询所有link到到的页面,需要加上参数galunique=true
:
(是的,this is documented,虽然不是很清楚。)
显然,link 目标将包含大量缺失的页面。事实上 link sources 似乎还包含一个空标题的缺失页面,这大概是由于维基百科 link 数据库中的错误记录。这可以通过重建(冗余)links table 来解决,但是,考虑到维基百科的大小,这将花费相当多的时间(在此期间,据推测,该站点必须被锁定read-only 模式以避免进一步的不一致)。
要在 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()
留作练习。另请注意,我还没有实际测试过这段代码;我 认为 没问题,但可能存在我遗漏的错误。它还会产生一个长得离谱的列表,并且可能会使您的浏览器变慢以致于爬行,这仅仅是因为 Wikipedia 有 lot 个页面。对于实际应用程序,您可能希望引入某种 on-demand 加载方案(例如,仅当用户向下滚动到当前列表末尾时才加载更多结果)。
这是我当前的代码。它完美地列出了页面标题,但链接都是 return '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);
}
将“&prop=links”and/or“&generator=alllinks”附加到 URL 似乎不会影响结果。
我想知道这部分应该包括什么:
'<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 />";
您可以直接使用页面 ID 创建 link:
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 />";
}
}
在同一个查询中您同时拥有 list=
和 generator=
这一事实向我表明您并不完全理解 generators 在 MediaWiki 中的工作方式 API.
基本上,生成器是一种使用 list as the source of pages to retrieve properties 的方式。 not 使用生成器作为另一个列表查询的输入没有任何意义。也就是说,您通常将 generator=
与 prop=
一起使用, 而不是 与 list=
。 MediaWiki(表面上)允许这样做的唯一原因是:
您可以使用页面列表(或生成器)进行查询,但没有
prop=
参数,like this。如果这样做,您只会获得页面的最小默认属性集(标题、命名空间和页面 ID)。您还可以将属性查询和列表查询合并到一个请求中,like this. You'll just get the results for both queries, merged into the same JSON/XML/etc. output, but they'll be otherwise completely separate. (You can also make multiple simultaneous list queries 这样。)
因此,当您将 generator=
与 list=
查询结合使用时,您将获得列表的常规输出和生成器匹配的页面的最小属性集。这两个输出不会以任何实际方式连接,除非是相同 API 响应的一部分。
无论如何,您想知道如何获取所有带有 links 的维基百科页面的标题和 URL。好吧,正如 schudel 在他们的回答中指出的那样,要获取某些页面的 URL,您需要 prop=info
和 inprop=url
;对于 运行 所有 linked 页面上的此查询,您可以使用 generator=alllinks
。因此,您最终得到:
请注意,这提供了所有包含 links from 的页面的信息。要运行查询所有link到到的页面,需要加上参数galunique=true
:
(是的,this is documented,虽然不是很清楚。)
显然,link 目标将包含大量缺失的页面。事实上 link sources 似乎还包含一个空标题的缺失页面,这大概是由于维基百科 link 数据库中的错误记录。这可以通过重建(冗余)links table 来解决,但是,考虑到维基百科的大小,这将花费相当多的时间(在此期间,据推测,该站点必须被锁定read-only 模式以避免进一步的不一致)。
要在 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()
留作练习。另请注意,我还没有实际测试过这段代码;我 认为 没问题,但可能存在我遗漏的错误。它还会产生一个长得离谱的列表,并且可能会使您的浏览器变慢以致于爬行,这仅仅是因为 Wikipedia 有 lot 个页面。对于实际应用程序,您可能希望引入某种 on-demand 加载方案(例如,仅当用户向下滚动到当前列表末尾时才加载更多结果)。