我试图使用API从维基数据ID中获取不同的维基百科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等)。 ATM我使用https://github.com/freearhey/wikidata:
$wdAPI = new \Wikidata\Wikidata();
$resp = $wdAPI->entities('Q7349');
但后来我不知道如何从实体()给出的对象中获取WP URL。我认为这应该是一项简单的任务,但几个小时之后我仍然无法弄清楚如何做到这一点,如果有使用WP API经验的人能够指出我正确的方向,我将非常感激:)
答案 0 :(得分:5)
我以前没有使用过这个特定的库,但是它的文档很简单,所以让我们一起讨论:
\Wikidata\Wikidata::entities()
返回Wikidata\Entity\Entity\EntityResponse
Wikidata\Entity\Entity\EntityResponse
有一个get()
方法,返回Wikidata\Entity\Entity
Wikidata\Entity\Entity
似乎没有任何函数可以返回相关维基百科页面的网站链接......死路一条。
基于此,看来这个图书馆不适合(截至2015年8月14日)您的需求。它只在currently only items contain sitelinks时实现基本实体数据。该库也不使用官方wikibase/data-model
库提供的数据模型。使用它会使事情变得更容易,因为它是Wikibase使用的那个,MediaWiki扩展实际上是Wikidata'底层软件。在该库中,您只需使用Wikibase\DataModel\Entity\Item
::getSiteLinkList()
获取站点链接列表(从版本0.4开始)。
使用上述数据模型库的替代库(也正在使用)将是addwiki/wikibase-api
。
有关GitHub repo的一些文档以及维基数据维基本身的更多文档("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
将包含所有网站链接,不仅包括维基百科网站,还包含维基词典和其他网站链接。此外,我们还没有网址。不幸的是,使用过的库没有提供一种开箱即用的方法来构建链接。相反,我们必须直接访问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";
}
}
这应该可以完成这项任务,即使第二部分有点hacky,因为我们创建了如何构建wiki链接的假设。从理论上讲,可能还有其他网址架构,但据我所知,所有维基媒体wiki都遵循这一方案。
无论如何,为了以完全安全的方式构建URL,应该有关于sitematrix
API模块返回的信息中提供的URL模式的信息,但是没有。