4

ユーザーにテキストの段落を要求し、それに対して何らかの操作を実行するWebページがあります。怠惰なユーザーにデモを行うために、ウィキペディアからランダムなテキストを取得して入力を入力する「Ifeellucky」ボタンを追加したいと思います。

Javascriptを使用して、ランダムなWikipediaの記事から一連のテキストをフェッチするにはどうすればよいですか?

ウィキペディアAPIを使用して記事をフェッチおよび解析する例をいくつか見つけましたが、それらはサーバー側である傾向があります。完全にクライアントから実行され、同一生成元ポリシーに惑わされないソリューションを探しています。

ランダムなジブリッシュでは不十分であることに注意してください。意味のある人間が読める文章が必要です。

4

1 に答える 1

11

私の答えは、ここで提案されている手法に基づいています。

トリッキーな部分は、正しいクエリ文字列を作成することです。

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

  • generator=randomランダムなページを選択します
  • prop=extracts500文字の抽出をexchars=500取得します
  • format=jsonJSON形式のデータを返します
  • 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で試すことができる完全な実例です。

<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つgenerator=randomは、実際の記事ではないトークページや生成コンテンツを頻繁に取得することです。誰かがクエリ文字列を改善して高品質の記事に制限できるなら、それは素晴らしいことです!

于 2013-03-08T12:08:03.907 に答える