从维基数据 ID 获取维基百科页面的 URL

Get Wikipedia pages' URLs from WikiData IDs

我正在尝试使用 API.[=12= 从维基数据 ID 获取不同的维基百科 URL(即 en.wikipedia.org/wiki/Page_Name) ]

例如,给定 URL http://www.wikidata.org/wiki/Q7349 I want to get links to Wikipedia articles in all languages (en.wikipedia.org/wiki/Joseph_Haydn, es.wikipedia.org/wiki/Joseph_Haydn, etc). ATM I'm using https://github.com/freearhey/wikidata:

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

但是我不知道如何从 entities() 给出的对象中获取 WP URLs。我想这应该是一件容易的事,但几个小时后我仍然无法弄清楚如何去做,如果以前有使用 WP API 经验的人能指出我在正确的方向:)

我之前没有使用过这个特定的库,但它的文档非常简单,所以让我们一起来了解一下:

  1. \Wikidata\Wikidata::entities() returns一个Wikidata\Entity\Entity\EntityResponse

  2. Wikidata\Entity\Entity\EntityResponse 有一个 get() 方法返回 Wikidata\Entity\Entity

  3. 的数组
  4. Wikidata\Entity\Entity 似乎没有任何功能向您返回指向相关维基百科页面的站点链接...死路一条。

基于此,该库似乎不适合(截至 2015 年 8 月 14 日)您的需求。它仅实现基本实体数据,同时 currently only items contain sitelinks. This library also does not use the data model offered by the official wikibase/data-model library. Using it would make things easier since it is the one being used by Wikibase, the MediaWiki extension which is actually Wikidata' underlying software. In that library you could simply use Wikibase\DataModel\Entity\Item::getSiteLinkList() 获取站点链接列表(从版本 0.4 开始)。

使用替代库的解决方案

使用上述数据模型库的替代库 - 也正在使用 - 将是 addwiki/wikibase-api.

在 GitHub 存储库上有一些文档,在维基数据维基本身 ("Wikidata:Creating a bot") 上有更多文档。

从该页面上的示例中,您可以获得一个基本概念,阅读一些 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 将包含 所有 站点链接,不仅指向 Wikipedia 站点,还指向 Wiktionary 和其他站点。此外,我们还没有 URLs。不幸的是,所用的库没有提供一种开箱即用的方式来构建链接。相反,我们必须直接访问维基数据 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";
    }
}

这应该可以完成工作,尽管第二部分有点老套,因为我们创建了一个关于如何构建 wiki 链接的假设。理论上可能还有其他 url 模式,但据我所知,所有维基媒体 wiki 都遵循这个模式。

无论如何,为了以完全安全的方式构建 URL,sitematrix [=63= 返回的信息中应该包含有关 URL 架构的信息] 模块但没有。