获取维基百科页面'来自WikiData ID

时间:2015-08-09 19:45:45

标签: php wikipedia-api wikidata

我试图使用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经验的人能够指出我正确的方向,我将非常感激:)

1 个答案:

答案 0 :(得分:5)

我以前没有使用过这个特定的库,但是它的文档很简单,所以让我们一起讨论:

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

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

  3. 数组
  4. Wikidata\Entity\Entity似乎没有任何函数可以返回相关维基百科页面的网站链接......死路一条。

  5. 基于此,看来这个图书馆不适合(截至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模式的信息,但是没有。