1

我正在尝试使用 API 从 Wikidata ID 获取不同的 Wikipedia URL(即 en.wikipedia.org/wiki/Page_Name)。

例如,给定 URL http://www.wikidata.org/wiki/Q7349我想获取所有语言的维基百科文章的链接(en.wikipedia.org/wiki/Joseph_Haydn,es.wikipedia.org/wiki/Joseph_Haydn , ETC)。ATM 我正在​​使用https://github.com/freearhey/wikidata

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

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

4

1 回答 1

5

我之前没有使用过这个特定的库,但它的文档相当简单,所以让我们一起来看看:

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

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

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

基于此,该库似乎不适合您的需求(截至 2015 年 8 月 14 日)。它只实现基本实体数据,而目前只有项目包含附加链接。该库也不使用官方wikibase/data-model库提供的数据模型。使用它会使事情变得更容易,因为它是 Wikibase 使用的,MediaWiki 扩展实际上是 Wikidata 的底层软件。在那个库中,您可以简单地使用来获取站点链接列表(从 0.4 版开始)。Wikibase\DataModel\Entity\Item::getSiteLinkList()

使用替代库的解决方案

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

GitHub repo 上有一些文档,Wikidata wiki 本身有一些文档(“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 和其他站点的链接。此外,我们还没有 URL。不幸的是,使用的库没有提供开箱即用的构建链接的方法。相反,我们必须直接访问 wikidata 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 模式,但据我所知,所有 Wikimedia wiki 都遵循这个模式。

无论如何,为了以完全安全的方式构建 URL,应该在sitematrixAPI 模块返回的信息中提供有关 URL 模式的信息,但没有。

于 2015-08-14T09:53:38.220 回答