2013-11-10 3 views
1

Есть ли какой-либо api или другой способ, с Javascript, для поиска в любой медиавике и печати найденной страницы (и если не найдена печать, которая).Поиск в mediawiki

Я предпочел бы что-то вроде этого:

function searchWiki(wikipage, search) { 
    //the function here 
    document.write(foundPage); 
} 

//run it 

searchWiki('https://en.wikipedia.org', 'banana'); 

//it would print 'https://en.wikipedia.org/wiki/Banana' 
+2

Заканчивать https://www.mediawiki.org/wiki/Api и, в частности, https://www.mediawiki.org/wiki/API:Search – IMSoP

ответ

5

Вот моя реализация такой функции. Он использует MediaWiki API через JSONP и довольно гибкий. Я думаю, что решение jQuery в порядке. Я создал small fiddle.

Википоиск (сайт, поиск, [обратный вызов], [опция])

function searchWiki(site, search, callback, opts) { 
    if(typeof callback == 'object') { 
     opts = callback; 
     callback = null; 
    } else { 
     opts = opts || {}; 
    } 
    // Build the required URLs 
    var siteUrl = (opts.ssl ? 'https' : 'http') + '://' + site; 
    var apiUrl = siteUrl + (opts.apiBase || '/w/') + 'api.php'; 
    var queryUrl = apiUrl + '?action=query&list=search&srsearch=' + encodeURIComponent(search) + '&srlimit=' + (opts.maxResults || 1) + '&format=json'; 
    // Issue the JSONP request 
    $.ajax(queryUrl + '&callback=?', { 
     dataType: 'jsonp', 
     // This prevents warnings about the unrecognized parameter "_" 
     cache: true, 
     success: function(data) { 
      // Get all returned pages 
      var titles = [], links = []; 
      for(var i = 0; i < data.query.search.length; i++) { 
       var title = data.query.search[i].title, 
        link = siteUrl + (opts.wikiBase || '/wiki/') + encodeURIComponent(title); 
       titles.push(title); 
       links.push(link); 
      } 
      if(!opts.maxResults) { 
       // Single result requested 
       if(data.query.search.length == 0) { 
        titles = links = null; 
       } else { 
        titles = titles[0]; 
        links = links[0]; 
       } 
      } 
      // Call the callback 
      (callback || opts.success || function(){})(titles, links); 
     } 
    }); 
} 

Пример 1: Одиночный поиск википедии

searchWiki('en.wikipedia.org', 'banana fruit', { 
    ssl: true, 
    success: function(title, link) { 
     // link is now "https://en.wikipedia.org/wiki/Banana" 
     if(title === null) { 
      $('#search-msg').text('Not found'); 
     } else { 
      var anchor = $('<a>').text(title).attr('href', link); 
      $('#search-msg').append(anchor); 
     } 
    } 
}); 

Этот пример показывает ссылку на википедию страницы с соответствующим заголовком.

Пример 2: Множественные результаты

searchWiki('www.mediawiki.org', 'Release notes', { 
    ssl: true, 
    maxResults: 5, 
    success: function(titles, links) { 
     for(var i = 0; i < titles.length; i++) { 
      alert('MediaWiki ' + titles[i] + ' at ' + links[i]); 
     } 
    } 
}); 

Этот пример отображает до пяти ссылок на MediaWiki страниц, которые соответствуют запросу «Примечания к выпуску».

Опции:

  • ssl: Использовать HTTPS вместо HTTP
  • maxResults: Возвращение несколько (до п) Результаты
  • apiBase: каталог API на целевом сайте (по умолчанию /w/)
  • wikiBase: Каталог Wiki на целевом сайте (по умолчанию /wiki/)
  • success: Функция для вызова после получения списка результатов

Вы можете либо передать функцию обратного вызова в качестве аргумента функции в (до опции) или в качестве опции success.


Обновление: Здесь чистый раствор JS (не JQuery не требуется). И there is another fiddle, на этот раз без jQuery.

function searchWiki(site, search, callback, opts) { 
    if(typeof callback == 'object') { 
     opts = callback; 
     callback = null; 
    } else { 
     opts = opts || {}; 
    } 
    // Build the required URLs 
    var siteUrl = (opts.ssl ? 'https' : 'http') + '://' + site; 
    var apiUrl = siteUrl + (opts.apiBase || '/w/') + 'api.php'; 
    var queryUrl = apiUrl + '?action=query&list=search&srsearch=' + encodeURIComponent(search) + '&srlimit=' + (opts.maxResults || 1) + '&format=json'; 
    var fnName = '_cb_' + Math.floor(Math.random() * 4294967296); 
    window[fnName] = function(data) { 
     // Clear references to this function 
     window[fnName] = null; 
     // Get all returned pages 
     var titles = [], links = []; 
     for(var i = 0; i < data.query.search.length; i++) { 
      var title = data.query.search[i].title, 
       link = siteUrl + (opts.wikiBase || '/wiki/') + encodeURIComponent(title); 
      titles.push(title); 
      links.push(link); 
     } 
     if(!opts.maxResults) { 
      // Single result requested 
      if(data.query.search.length == 0) { 
       titles = links = null; 
      } else { 
       titles = titles[0]; 
       links = links[0]; 
      } 
     } 
     // Call the callback 
     (callback || opts.success || function(){})(titles, links); 
    } 
    // Issue the JSONP request 
    var scriptTag = document.createElement('script'); 
    scriptTag.setAttribute('src', queryUrl + '&callback=' + fnName); 
    document.head.appendChild(scriptTag); 
} 

Обновление 2: Наконец решение для Node.js.API все то же, но она дает некоторые дополнительных опции:

  • error: обратный вызов ошибки (это было невозможно в браузере на основе JS)
  • userAgent: Строка пользовательского агента пользователя как suggested in the docs
  • port: Целевой порт (по умолчанию 80/443)
  • encoding: кодирование ответа (по умолчанию в utf8)

Я не очень много тестировал, но примеры (см. Выше) все равно должны работать.

var http = require('http'), 
    https = require('https'); 

function searchWiki(site, search, callback, opts) { 
    if(typeof callback == 'object') { 
     opts = callback; 
     callback = null; 
    } else { 
     opts = opts || {}; 
    } 
    // Build the required paths 
    var apiPath = (opts.apiBase || '/w/') + 'api.php'; 
    var queryPath = apiPath + '?action=query&list=search&srsearch=' + encodeURIComponent(search) + '&srlimit=' + (opts.maxResults || 1) + '&format=json'; 
    // Request options 
    var httpOpts = { 
     hostname: site, 
     port: (opts.port ? opts.port : (opts.ssl ? 443 : 80)), 
     method: 'GET', 
     path: queryPath, 
     agent: false 
    }; 
    // Custom user agent 
    if(opts.userAgent) { 
     httpOpts.headers = { 
      'User-Agent': opts.userAgent 
     }; 
    } 
    // Make the request 
    var req = (opts.ssl ? https : http).request(httpOpts, function(res) { 
     var msgBody = ''; 
     res.setEncoding(opts.encoding || 'utf8'); 

     res.on('data', function(chunk) { 
      msgBody += chunk; 
     }); 

     res.on('end', function() { 
      // Parse response as JSON 
      var data; 
      try { 
       data = JSON.parse(msgBody); 
      } catch(err) { 
       (opts.error || function(){})(err); 
       return; 
      } 
      // Get all returned pages 
      var siteUrl = (opts.ssl ? 'https' : 'http') + '://' + site; 
      var titles = [], links = []; 
      for(var i = 0; i < data.query.search.length; i++) { 
       var title = data.query.search[i].title, 
        link = siteUrl + (opts.wikiBase || '/wiki/') + encodeURIComponent(title); 
       titles.push(title); 
       links.push(link); 
      } 
      if(!opts.maxResults) { 
       // Single result requested 
       if(data.query.search.length == 0) { 
        titles = links = null; 
       } else { 
        titles = titles[0]; 
        links = links[0]; 
       } 
      } 
      // Call the callback 
      (callback || opts.success || function(){})(titles, links); 
     }); 
    }); 
    req.on('error', function(err) { 
     (opts.error || function(){})(err); 
    }); 
    req.end(); 
} 
+0

я не должен использовать JQuery, но выглядит так, как будто я хочу, поэтому, возможно, я тоже смогу использовать JQuery, хотя я и не планировал этого. – PMint

+0

@PMint Я переписал некоторые части функции для работы без jQuery. Он по-прежнему обеспечивает те же функции, что и раньше. –

+0

Это работает, но есть ли способ сделать эту работу с Node.js? Ajax не работает с пакетом jquery, и окно тоже не работает, потому что это Node.js. Я согласен с ответом, поскольку я не упоминал Node.js, но это то, к чему я на самом деле нахожусь. – PMint