Получение URL-адресов страниц Википедии из идентификаторов WikiData

Я пытаюсь получить разные URL-адреса Википедии (например, en.wikipedia.org/wiki/Page_Name) из идентификатора Wikidata с помощью API.

Например, учитывая URL-адрес http://www.wikidata.org/wiki/Q7349, я хочу чтобы получить ссылки на статьи Википедии на всех языках (en.wikipedia.org/wiki/Joseph_Haydn, es.wikipedia.org/wiki/Joseph_Haydn и т. д.). Я использую банкомат https://github.com/freearhey/wikidata:

$wdAPI = new \Wikidata\Wikidata();
$resp = $wdAPI->entities('Q7349');

но тогда я не знаю, как получить URL-адреса WP из объекта, заданного entity (). Я полагаю, что это должна быть простая задача, но через несколько часов я все еще не могу понять, как это сделать, и я был бы очень признателен, если бы кто-то с предыдущим опытом использования WP API мог указать мне правильное направление :)


person Héctor Arroyo    schedule 09.08.2015    source источник


Ответы (1)


Я раньше не работал с этой конкретной библиотекой, но ее документация довольно проста, поэтому давайте рассмотрим ее вместе:

  1. \Wikidata\Wikidata::entities() возвращает Wikidata\Entity\Entity\EntityResponse

  2. Wikidata\Entity\Entity\EntityResponse имеет get() метод, возвращающий массив Wikidata\Entity\Entity

  3. Wikidata\Entity\Entity, похоже, не имеет функции, возвращающей вам ссылки сайта на соответствующие страницы Википедии ... тупик.

Исходя из этого, похоже, что эта библиотека не подходит (по состоянию на 14 августа 2015 года) для ваших нужд. Он реализует только базовые данные объекта, в то время как в настоящее время только элементы содержат дополнительные ссылки. Эта библиотека также не использует модель данных, предлагаемую официальной библиотекой wikibase/data-model. Его использование упростило бы задачу, поскольку именно оно используется Wikibase, расширением MediaWiki, которое на самом деле является базовым программным обеспечением Wikidata. В этой библиотеке вы можете просто использовать Wikibase\DataModel\Entity\Item ::getSiteLinkList(), чтобы получить список ссылок на сайты (начиная с версии 0.4).

Решение с использованием альтернативной библиотеки

Альтернативной библиотекой, которая использует упомянутую выше библиотеку модели данных, которая также используется, будет addwiki/wikibase-api < / а>.

Есть некоторая документация по репозиторию GitHub и еще немного документации по самой вики-странице Wikidata ("Wikidata : Создание бота »).

Из примеров на этой странице вы можете получить базовое представление, прочитав некоторую документацию по API, вы можете создать следующий код:

use \Mediawiki\Api as MwApi;
use \Wikibase\Api as WbApi;
use \Wikibase\DataModel\SiteLink;

$api = new MwApi\MediawikiApi( "http://www.wikidata.org/w/api.php" );
$api->login( new MwApi\ApiUser( 'USER', 'PASSWORD' ) );
$wikidata = new WbApi\WikibaseFactory( $api );


// Get the current revision of item Q7349
$revision = $wikidata->newRevisionGetter()->getFromId( 'Q7349' );

/** @var \Wikibase\DataModel\Entity\Item $item */
$item = $revision->getContent()->getData();

/** @var SiteLink $siteLink */
$itemSiteLinks = $item->getSiteLinkList();

Таким образом, $itemSiteLinks будет содержать все ссылки сайтов не только на сайты Википедии, но также на Викисловарь и другие. Кроме того, у нас еще нет URL-адресов. К сожалению, используемая библиотека не позволяет создавать ссылки из коробки. Вместо этого мы должны напрямую обращаться к API викиданных, чтобы получить информацию обо всех сайтах, а затем строить ссылки на основе этой информации.

/**
 * @param MwApi\MediawikiApi $mwApi
 * @param string[] $projectTypes The desired projects, e.g. [ "Wikipedia", "Wiktionary" ]
 * @return string[] Project's ID as key, url string as value.
 */
function getProjectUrls( MwApi\MediawikiApi $mwApi, $projectTypes ) {
    $urls = [];
    // TODO: Could optimize this request with additional parameters:
    $siteMatrix = $mwApi->postRequest( new \Mediawiki\Api\SimpleRequest( 'sitematrix' ) )[ 'sitematrix' ];

    foreach( $siteMatrix as $key => $wmProjectsByLang ) {
        if( !is_numeric( $key ) ) {
            continue; // not a project but meta info (e.g. "count")
        }
        foreach( $wmProjectsByLang[ 'site' ] as $mwProject ) {
            if( in_array( $mwProject[ 'sitename' ], $projectTypes ) ) {
                $urls[ $mwProject[ 'dbname' ] ] = $mwProject[ 'url' ];
            }
        }
    }
    return $urls;
}

/**
 * @param SiteLink $siteLink
 * @param array $sitesInfo
 * @return null|string
 */
function buildSiteLinkUrl( SiteLink $siteLink, array $sitesInfo ) {
    $siteId = $siteLink->getSiteId();

    if( !array_key_exists( $siteId, $sitesInfo ) ) {
        return null;
    }
    $baseUrl = $sitesInfo[ $siteId ];
    $titlePart = urlencode( str_replace( ' ', '_', $siteLink->getPageName() ) );

    return "$baseUrl/wiki/$titlePart";
}

$wikipediaSites = getProjectUrls( $api, [ 'Wikipedia' ] );

foreach( $itemSiteLinks as $siteLink ) {
    $url = buildSiteLinkUrl( $siteLink, $wikipediaSites );
    if( $url !== null ) {
        echo "$url\n";
    }
}

Это должно сработать, даже несмотря на то, что вторая часть является своего рода взломом, поскольку мы сделали предположение о том, как создаются ссылки вики. Теоретически могут быть другие схемы URL-адресов, но, насколько я знаю, все вики-страницы Викимедиа следуют этой.

В любом случае, для создания URL-адресов совершенно безопасным способом в информации, возвращаемой модулем sitematrix API, должна быть информация о схемах URL-адресов, но ее нет.

person Daniel A. R. Werner    schedule 14.08.2015