从 Wikipedia 获取随机摘录(Javascript,仅限客户端)
Posted
技术标签:
【中文标题】从 Wikipedia 获取随机摘录(Javascript,仅限客户端)【英文标题】:Fetch random excerpt from Wikipedia (Javascript, client-only) 【发布时间】:2013-02-23 23:29:36 【问题描述】:我有一个网页,它要求用户输入一段文本,然后对其执行一些操作。为了向懒惰的用户演示它,我想添加一个“我觉得很幸运”按钮,它会从 Wikipedia 中抓取一些随机文本并填充输入。
如何使用 javascript 从随机的 Wikipedia 文章中获取文本序列?
我发现了一些使用Wikipedia API 的fetching 和parsing 文章的示例,但它们往往是服务器端的。我正在寻找一个完全从客户端运行并且不会被same origin policy 破坏的解决方案。
注意随机乱码是不够的;我需要人类可读的有意义的句子。
【问题讨论】:
【参考方案1】:我的答案基于suggested here 技术。
棘手的部分是制定正确的查询字符串:
http://en.wikipedia.org/w/api.php?action=query&generator=random&prop=extracts&exchars=500&format=json&callback=onWikipedia
generator=random
随机选择一个页面
prop=extracts
和 exchars=500
检索 500 个字符的摘录
format=json
返回 JSON 格式的数据
callback=
导致该数据被包装在一个函数调用中,因此它可以像任何其他 <script>
一样被处理并注入您的页面(请参阅JSONP),从而绕过跨域障碍。
可以选择添加requestid
,每次都使用一个新值,以避免浏览器缓存中的结果过时(IE9 中需要)
查询提供的页面看起来像这样(为了便于阅读,我添加了空格):
onWikipedia(
"query":
"pages":
"12362520":
"pageid":12362520,
"ns":0,
"title":"Power Building",
"extract":"<p>The <b>Power Building<\/b> is a historic commercial building in
the downtown of Cincinnati, Ohio, United States. Built in 1903, it
was designed by Harry Hake. It was listed on the National Register
of Historic Places on March 5, 1999. One week later, a group of
buildings in the northeastern section of downtown was named a
historic district, the Cincinnati East Manufacturing and Warehouse
District; the Power Building is one of the district's contributing
properties.<\/p>\n<h2> Notes<\/h2>"
)
当然,您每次都会收到不同的文章。
这是一个完整的工作示例,您可以在 JSBin 上try out。
<html><BODY>
<p><textarea id="textbox" style="width:350px; height:150px"></textarea></p>
<p><button type="button" id="button" onclick="startFetch(100, 500)">
Fetch random Wikipedia extract</button></p>
<script type="text/javascript">
var textbox = document.getElementById("textbox");
var button = document.getElementById("button");
var tempscript = null, minchars, maxchars, attempts;
function startFetch(minimumCharacters, maximumCharacters, isRetry)
if (tempscript) return; // a fetch is already in progress
if (!isRetry)
attempts = 0;
minchars = minimumCharacters; // save params in case retry needed
maxchars = maximumCharacters;
button.disabled = true;
button.style.cursor = "wait";
tempscript = document.createElement("script");
tempscript.type = "text/javascript";
tempscript.id = "tempscript";
tempscript.src = "http://en.wikipedia.org/w/api.php"
+ "?action=query&generator=random&prop=extracts"
+ "&exchars="+maxchars+"&format=json&callback=onFetchComplete&requestid="
+ Math.floor(Math.random()*999999).toString();
document.body.appendChild(tempscript);
// onFetchComplete invoked when finished
function onFetchComplete(data)
document.body.removeChild(tempscript);
tempscript = null
var s = getFirstProp(data.query.pages).extract;
s = htmlDecode(stripTags(s));
if (s.length > minchars || attempts++ > 5)
textbox.value = s;
button.disabled = false;
button.style.cursor = "auto";
else
startFetch(0, 0, true); // retry
function getFirstProp(obj)
for (var i in obj) return obj[i];
// This next bit borrowed from Prototype / hacked together
// You may want to replace with something more robust
function stripTags(s)
return s.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, "");
function htmlDecode(input)
var e = document.createElement("div");
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
</script>
</BODY></HTML>
generator=random
的一个缺点是您经常会收到并非实际文章的讨论页面或生成的内容。如果有人可以改进查询字符串以将其限制为优质文章,那就太好了!
【讨论】:
另请查看 Wikipedia API 中的origin
参数。它支持 CORS,因此您可以使用传统的 AJAX 而无需进行 JSONP 注入。
可以使用api的explaintext
参数来摆脱html,而不是使用正则表达式
嗨@rkagerer。感谢您在上面的 CORS 评论。您愿意分享一个实现 AJAX 方法的示例吗? documentation 周围的 origin
参数是指 $wgCrossSiteAJAXdomains
但我还没有找到一个示例来说明如何在客户端使用或不使用 jquery。以上是关于从 Wikipedia 获取随机摘录(Javascript,仅限客户端)的主要内容,如果未能解决你的问题,请参考以下文章