2013-03-08 49 views
4

我有一個網頁,要求用戶輸入一段文字,然後對其執行一些操作。爲了演示給懶惰的用戶,我想添加一個「我感覺很幸運」的按鈕,它將從維基百科中獲取一些隨機文本並填充輸入。從維基百科獲取隨機摘錄(Javascript,僅客戶端)

如何使用Javascript從維基百科隨機文章中獲取文本序列?

我發現fetchingparsing文章使用Wikipedia API的一些例子,但它們往往是服務器端。我正在尋找一個完全從客戶端運行的解決方案,並且不會受到same origin policy的困擾。

注意隨機亂碼是不夠的;我需要有意義的人類可讀的句子。

回答

11

我的答案建立在技術suggested here上。

棘手的部分是配製正確的查詢字符串:

http://en.wikipedia.org/w/api.php?action=query&generator=random&prop=extracts&exchars=500&format=json&callback=onWikipedia

  • generator=random選擇隨機頁面
  • prop=extractsexchars=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。的generator=random

<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> 

一個缺點是你經常收到不實際的文章討論頁或生成的內容。如果任何人都可以改善查詢字符串以將其限制爲高質量的文章,那就太棒了!

+1

另請參閱Wikipedia API中的'origin'參數。它支持** [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)**,因此您可以使用傳統的AJAX而無需執行JSONP注入。 – rkagerer 2013-03-08 13:17:45

+1

而不是使用正則表達式可以使用API​​的'explaintext'參數來擺脫html – worenga 2013-09-18 23:22:32

+1

Hi @rkagerer。我非常感謝你上面的CORS評論。你願意分享一個實現AJAX方法的例子嗎? [文檔](https://www.mediawiki。org/wiki/Manual:CORS)圍繞'origin'參數引用'$ wgCrossSiteAJAXdomains',但是我還沒有找到一個例子展示如何在客戶端使用或不使用jquery。 – 2016-04-30 14:18:28