【问题标题】:Accessing main picture of wikipedia page by API通过API访问维基百科页面的主图
【发布时间】:2023-03-25 03:40:01
【问题描述】:

我有什么方法可以使用 API 访问任何维基百科页面的缩略图?我的意思是盒子右上角的图像。有没有相关的 API?

【问题讨论】:

  • 这里的所有答案都是不可靠的 hack,通常会给出错误的图像。 stackoverflow.com/questions/36813352/… 的答案更频繁地给出图像并且它永远不会是错误的图像。我建议合并这两个问题。

标签: php api wikipedia-api


【解决方案1】:

您可以使用prop=pageimages 获取任何维基百科页面的缩略图。例如:

http://en.wikipedia.org/w/api.php?action=query&titles=Al-Farabi&prop=pageimages&format=json&pithumbsize=100

您将获得缩略图完整的 URL。

【讨论】:

  • 这是一个很好的解决方案,但(作为记录)它基于标记为“实验性”的新 API 扩展。 mediawiki.org/wiki/Extension:PageImages
  • 也许它是实验性的,但它确实有效!第二个示例,展示如何在一个查询中从多个页面获取缩略图:en.wikipedia.org/w/…
  • 如果您有维基百科(数字)ID 而不是维基百科的标题,有没有办法获得同样的信息?
  • 据我所知,我需要知道我可以访问图像的数字 14533,但它一直在变化,那么我该如何打开它? {"batchcomplete":"","query":{"pages":{"14533":{"pageid":14533,"ns":0,"title":"India","thumbnail":{"original ":"upload.wikimedia.org/wikipedia/en/4/41/Flag_of_India.svg"}}}}}
  • @LaurynasG - 您想在 api 调用中使用 formatversion=2。 https://en.wikipedia.org/w/api.php?action=query&formatversion=2&prop=pageimages%7Cpageterms&titles=Albert%20Einstein
【解决方案2】:

http://en.wikipedia.org/w/api.php

prop=images

它返回在解析页面中使用的图像文件名数组。然后,您可以选择进行另一个 API 调用以找出完整的图像 URL,例如: action=query&titles=Image:INSERT_EXAMPLE_FILE_NAME_HERE.jpg&prop=imageinfo&iiprop=url

或发送至calculate the URL via the filename's hash

不幸的是,虽然prop=images 返回的图像数组按照它们在页面上的顺序排列,但不能保证第一个是信息框中的图像,因为有时页面会在信息框(大多数时候是关于页面元数据的图标:例如“这篇文章被锁定”)。

在图像数组中搜索包含页面标题的第一张图像可能是信息框图像的最佳猜测。

【讨论】:

  • 完美,我不知道这个。
  • 我可以使用道具访问图像,但它给了我多张照片en.wikipedia.org/w/…。我不知道哪一张是主图。
  • @Aby,我认为这只是一个图片列表,你无法获得真实的图片URL,所以你可以参考我的anwser。如果你想查看 api 文档,请看这个http://www.mediawiki.org/wiki/API:FAQ
  • 最好使用 API 调用而不是自己计算,因为您仍然不知道它是否在 Commons 中,例如/commons/a/ae/Filename.jpg 或特定语言 /en/a/ae/Filename.jpg
  • 现在有一个名为 pageimages 的新属性,用于过滤掉默认图像。
【解决方案3】:

【讨论】:

  • 这个答案很简短,但很有效! pageimages 可能是新属性,这就是为什么前面没有介绍它,而是获取页面的主图像。
  • 优雅! pageimages 属性就是它。它的结果可能是信息框模板中的第一张图片。如果您将图像添加到 prop=,那么您也会获得页面上的所有其他图像。 (en.wikipedia.org/w/…)
  • 这是最好的答案
  • 请注意,如果您还想获取非免费缩略图(例如,视频游戏、电影等),还需要添加 &pilicense=any
【解决方案4】:

查看 MediaWiki API 示例以获取维基百科页面的主图片:https://www.mediawiki.org/wiki/API:Page_info_in_search_results

正如其他人所提到的,您将在 API 查询中使用 prop=pageimages

如果您还需要图像描述,您可以在 API 查询中使用 prop=pageimages|pageterms

您可以使用piprop=original 获取原始图像。或者您可以获得具有指定宽度/高度的缩略图。对于宽度/高度=600 的缩略图,piprop=thumbnail&pithumbsize=600。如果省略其中一个,API 回调中返回的图像将默认为宽度/高度为 50 像素的缩略图。

如果您以 JSON 格式请求结果,则应始终在 API 查询中使用 formatversion=2(即 format=json&formatversion=2),因为这样可以更轻松地从查询中检索图像。

原始尺寸图片:

https://en.wikipedia.org/w/api.php?action=query&format=json&formatversion=2&prop=pageimages|pageterms&piprop=original&titles=Albert Einstein

缩略图大小(600px 宽/高)图片:

https://en.wikipedia.org/w/api.php?action=query&format=json&formatversion=2&prop=pageimages|pageterms&piprop=thumbnail&pithumbsize=600&titles=Albert Einstein

【讨论】:

  • 请注意,如果维基百科使用非免费图像,pageimages 将不会返回图像 url。例如,尝试检索 Family Guy 的图像将不会返回图像:https://en.wikipedia.org/w/api.php?action=query&format=json&formatversion=2&prop=pageimages|pageterms&piprop=original&titles=Family%20Guy
  • 请注意,如果您还想获取非免费缩略图(例如,用于视频游戏、电影等),还需要添加 &pilicense=any
【解决方案5】:

方式一:你可以试试这样的查询:

http://en.wikipedia.org/w/api.php?action=opensearch&limit=5&format=xml&search=italy&namespace=0

在响应中,您可以看到Image 标签。

<Item>
<Text xml:space="preserve">Italy national rugby union team</Text>
<Description xml:space="preserve">
The Italy national rugby union team represent the nation of Italy in the sport of rugby union.
</Description>
<Url xml:space="preserve">
http://en.wikipedia.org/wiki/Italy_national_rugby_union_team
</Url>
<Image source="http://upload.wikimedia.org/wikipedia/en/thumb/4/46/Italy_rugby.png/43px-Italy_rugby.png" width="43" height="50"/>
</Item>

方式2:使用查询http://en.wikipedia.org/w/index.php?action=render&title=italy

然后你可以得到一个原始的html代码,你可以使用PHP Simple HTML DOM Parser这样的东西来获取图像 http://simplehtmldom.sourceforge.net

我没有时间给你写信。只是给你一些建议,谢谢。

【讨论】:

  • 这是一个开放式搜索,这可能会提供多个搜索页面..
  • @Aby,我也研究了很久wiki api document。所以这两种方法是我认为可以得到图像的方法。在我看来,我喜欢方式2,因为如果页面上有图像,您可以通过dom parse轻松将它们取出。因为所有的 wiki 页面都是由代码生成的,所以你可以很容易地从中找到共同点。他们总是躺在tabledivclass aaaclass bbb 中。这就是我的全部建议。
【解决方案6】:

很抱歉没有具体回答您关于图片的问题。但这里有一些代码可以获取所有图像的列表:

function makeCall($url) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    return curl_exec($curl);
}

function wikipediaImageUrls($url) {
    $imageUrls = array();
    $pathComponents = explode('/', parse_url($url, PHP_URL_PATH));
    $pageTitle = array_pop($pathComponents);
    $imagesQuery = "http://en.wikipedia.org/w/api.php?action=query&titles={$pageTitle}&prop=images&format=json";
    $jsonResponse = makeCall($imagesQuery);
    $response = json_decode($jsonResponse, true);
    $imagesKey = key($response['query']['pages']);
    foreach($response['query']['pages'][$imagesKey]['images'] as $imageArray) {
        if($imageArray['title'] != 'File:Commons-logo.svg' && $imageArray['title'] != 'File:P vip.svg') {
            $title = str_replace('File:', '', $imageArray['title']);
            $title = str_replace(' ', '_', $title);
            $imageUrlQuery = "http://en.wikipedia.org/w/api.php?action=query&titles=Image:{$title}&prop=imageinfo&iiprop=url&format=json";
            $jsonUrlQuery = makeCall($imageUrlQuery);
            $urlResponse = json_decode($jsonUrlQuery, true);
            $imageKey = key($urlResponse['query']['pages']);
            $imageUrls[] = $urlResponse['query']['pages'][$imageKey]['imageinfo'][0]['url'];
        }
    }
    return $imageUrls;
}
print_r(wikipediaImageUrls('http://en.wikipedia.org/wiki/Saturn_%28mythology%29'));
print_r(wikipediaImageUrls('http://en.wikipedia.org/wiki/Hans-Ulrich_Rudel'));

我为http://en.wikipedia.org/wiki/Saturn_%28mythology%29买了这个:

Array
(
    [0] => http://upload.wikimedia.org/wikipedia/commons/1/10/Arch_of_SeptimiusSeverus.jpg
    [1] => http://upload.wikimedia.org/wikipedia/commons/8/81/Ivan_Akimov_Saturn_.jpg
    [2] => http://upload.wikimedia.org/wikipedia/commons/d/d7/Lucius_Appuleius_Saturninus.jpg
    [3] => http://upload.wikimedia.org/wikipedia/commons/2/2c/Polidoro_da_Caravaggio_-_Saturnus-thumb.jpg
    [4] => http://upload.wikimedia.org/wikipedia/commons/b/bd/Porta_Maggiore_Alatri.jpg
    [5] => http://upload.wikimedia.org/wikipedia/commons/6/6a/She-wolf_suckles_Romulus_and_Remus.jpg
    [6] => http://upload.wikimedia.org/wikipedia/commons/4/45/Throne_of_Saturn_Louvre_Ma1662.jpg
)

对于第二个 URL (http://en.wikipedia.org/wiki/Hans-Ulrich_Rudel):

Array
(
    [0] => http://upload.wikimedia.org/wikipedia/commons/e/e9/BmRKEL.jpg
    [1] => http://upload.wikimedia.org/wikipedia/commons/3/3f/BmRKELS.jpg
    [2] => http://upload.wikimedia.org/wikipedia/commons/2/2c/Bundesarchiv_Bild_101I-655-5976-04%2C_Russland%2C_Sturzkampfbomber_Junkers_Ju_87_G.jpg
    [3] => http://upload.wikimedia.org/wikipedia/commons/6/62/Bundeswehr_Kreuz_Black.svg
    [4] => http://upload.wikimedia.org/wikipedia/commons/9/99/Flag_of_German_Reich_%281935%E2%80%931945%29.svg
    [5] => http://upload.wikimedia.org/wikipedia/en/6/64/HansUlrichRudel.jpeg
    [6] => http://upload.wikimedia.org/wikipedia/commons/8/82/Heinkel_He_111_during_the_Battle_of_Britain.jpg
    [7] => http://upload.wikimedia.org/wikipedia/commons/6/66/Regulation_WW_II_Underwing_Balkenkreuz.png
)

请注意,URL 在第二个数组的第 6 个元素上发生了一些变化。这是@JosephJaber 在上面的评论中警告的内容。

希望这对某人有所帮助。

【讨论】:

  • 如果有人需要实际查看要引用哪些对象键以从获取响应中检索图像,这就是答案!谢谢!
【解决方案7】:

我已经编写了一些通过维基百科文章标题获取主图像(完整 URL)的代码。这并不完美,但总的来说我对结果非常满意。

挑战在于,当查询特定标题时,维基百科会返回多个图像文件名(没有路径)。此外,辅助搜索(我使用了此线程中发布的代码 varatis - 谢谢!)返回基于搜索的图像文件名找到的所有图像的 URL,无论原始文章标题如何。毕竟,我们最终可能会得到与搜索无关的通用图像,因此我们将其过滤掉。代码迭代文件名和 URL,直到找到(希望是最好的)匹配...有点复杂,但它有效:)

关于通用过滤器的注意事项:我一直在为 isGeneric() 函数编译通用图像字符串列表,但该列表一直在增长。我正在考虑将其保留为公开列表 - 如果有任何兴趣,请告诉我。

上一篇:

protected static $baseurl = "http://en.wikipedia.org/w/api.php";

主函数 - 从标题中获取图片 URL:

public static function getImageURL($title)
{
    $images = self::getImageFilenameObj($title); // returns JSON object
    if (!$images) return '';

    foreach ($images as $image)
    {
        // get object of image URL for given filename
        $imgjson = self::getFileURLObj($image->title);

        // return first image match
        foreach ($imgjson as $img)
        {
            // get URL for image
            $url = $img->imageinfo[0]->url;

            // no image found               
            if (!$url) continue;

            // filter generic images
            if (self::isGeneric($url)) continue;

            // match found
            return $url;
        }
    }
    // match not found
    return '';          
}

== 上面的main函数调用了以下函数==

按标题获取 JSON 对象(文件名):

public static function getImageFilenameObj($title)
{
    try     // see if page has images
    {
        // get image file name
        $json = json_decode(
            self::retrieveInfo(
                self::$baseurl . '?action=query&titles=' .
                urlencode($title) . '&prop=images&format=json'
            ))->query->pages;

        /** The foreach is only to get around
         *  the fact that we don't have the id.
         */
        foreach ($json as $id) { return $id->images; }
    }
    catch(exception $e) // no images
    {
        return NULL;
    }
}   

通过文件名获取 JSON 对象(URL):

public static function getFileURLObj($filename)
{
    try                     // resolve URL from filename
    {
        return json_decode(
            self::retrieveInfo(
                self::$baseurl . '?action=query&titles=' .
                urlencode($filename) . '&prop=imageinfo&iiprop=url&format=json'
            ))->query->pages;
    }
    catch(exception $e)     // no URLs
    {
        return NULL;
    }
}   

过滤掉通用图片:

public static function isGeneric($url)
{
    $generic_strings = array(
        '_gray.svg',
        'icon',
        'Commons-logo.svg',
        'Ambox',
        'Text_document_with_red_question_mark.svg',
        'Question_book-new.svg',
        'Canadese_kano',
        'Wiki_letter_',
        'Edit-clear.svg',
        'WPanthroponymy',
        'Compass_rose_pale',
        'Us-actor.svg',
        'voting_box',
        'Crystal_',
        'transportation_inv',
        'arrow.svg',
        'Quill_and_ink-US.svg',
        'Decrease2.svg',
        'Rating-',
        'template',
        'Nuvola_apps_',
        'Mergefrom.svg',
        'Portal-',
        'Translation_to_',
        '/School.svg',
        'arrow',
        'Symbol_',
        'stub',
        'Unbalanced_scales.svg',
        '-logo.',
        'P_vip.svg',
        'Books-aj.svg_aj_ashton_01.svg',
        'Film',
        '/Gnome-',
        'cap.svg',
        'Missing',
        'silhouette',
        'Star_empty.svg',
        'Music_film_clapperboard.svg',
        'IPA_Unicode',
        'symbol',
        '_highlighting_',
        'pictogram',
        'Red_pog.svg',
        '_medal_with_cup',
        '_balloon',
        'Feature',
        'Aiga_'
    );

    foreach ($generic_strings as $str)
    {
        if (stripos($url, $str) !== false) return true;
    }

    return false;
}

欢迎评论。

【讨论】:

    【解决方案8】:

    我有一种方法可以可靠地获取维基百科页面的主图像 - 名为 PageImages 的扩展

    PageImages 扩展收集有关页面上使用的图像的信息。

    它的目的是返回一个最合适的相关缩略图 与一篇文章,试图只返回有意义的图像,例如不是 来自维护模板、存根或标志图标的那些。目前它 使用页面中使用的第一个无意义的图像。

    https://www.mediawiki.org/wiki/Extension:PageImages

    只需将道具 pageimages 添加到您的 API 查询中:

    /w/api.php?action=query&prop=pageimages&titles=Somepage&format=xml
    

    这可以可靠地过滤掉烦人的默认图像,并让您不必自己过滤它们!该扩展安装在所有主要的维基百科页面上......

    【讨论】:

      【解决方案9】:

      让我们以页面http://en.wikipedia.org/wiki/index.html?curid=57570为例 获取主图

      看看

      prop=pageprops

      action=query&pageids=57570&prop=pageprops&format=json

      结果页面数据例如

      { "pages" : { "57570":{
                          "pageid":57570,
                          "ns":0,
                          "title":"Sachin Tendulkar",
                          "pageprops" : {
                               "defaultsort":"Tendulkar,Sachin",
                               "page_image":"Sachin_at_Castrol_Golden_Spanner_Awards_(crop).jpg",
                               "wikibase_item":"Q9488"
                          }
                  }
                }
       }}

      我们得到这个结果的主图片文件名

      ** (wikiId).pageprops.page_image = Sachin_at_Castrol_Golden_Spanner_Awards_(crop).jpg**

      现在我们有了图像文件名,我们将不得不进行另一个 Api 调用以从文件名中获取完整的图像路径,如下所示

      action=query&titles=Image:INSERT_EXAMPLE_FILE_NAME_HERE.jpg&prop=imageinfo&iiprop=url

      例如。

      action=query&titles=Image:Sachin_at_Castrol_Golden_Spanner_Awards_(crop).jpg&prop=imageinfo&iiprop=url

      返回包含 url 的图像数据数组 http://upload.wikimedia.org/wikipedia/commons/3/35/Sachin_at_Castrol_Golden_Spanner_Awards_%28crop%29.jpg

      【讨论】:

        【解决方案10】:

        就像 Anuraj 提到的,pageimages 参数就是它。看看下面的 url,它会带来一些漂亮的东西:

        https://en.wikipedia.org/w/api.php?action=query&prop=info|extracts|pageimages|images&inprop=url&exsentences=1&titles=india
        

        她是一些有趣的参数:

        • extractsexsentences 这两个参数给你一个简短的 您可以使用的描述。 (exsentences 是您要在摘录中包含的句子数)
        • info 和 inprop=url 参数为您提供页面的 url
        • prop 属性有多个参数,以条形符号分隔
        • 如果你在里面插入format=json,那就更好了

        【讨论】:

          【解决方案11】:

          this related question on an API for Wikipedia。但是,我不知道是否可以通过 API 检索缩略图。

          您也可以考虑只解析网页以查找图像 URL,并以这种方式检索图像。

          【讨论】:

          • 感谢您的回复,但是在维基百科页面上获取图片有点不可能
          【解决方案12】:

          这是我为 95% 的文章找到的 XPath 列表。主要是 1、2、3 和 4。很多文章格式不正确,这些都是边缘情况:

          您可以使用 DOM 解析库通过 XPath 获取图像。

          static NSString   *kWikipediaImageXPath2    =   @"//*[@id=\"mw-content-text\"]/div[1]/div/table/tr[2]/td/a/img";
          static NSString   *kWikipediaImageXPath3    =   @"//*[@id=\"mw-content-text\"]/div[1]/table/tr[1]/td/a/img";
          static NSString   *kWikipediaImageXPath1    =   @"//*[@id=\"mw-content-text\"]/div[1]/table/tr[2]/td/a/img";
          static NSString   *kWikipediaImageXPath4    =   @"//*[@id=\"mw-content-text\"]/div[2]/table/tr[2]/td/a/img";
          static NSString   *kWikipediaImageXPath5    =   @"//*[@id=\"mw-content-text\"]/div[1]/table/tr[2]/td/p/a/img";
          static NSString   *kWikipediaImageXPath6    =   @"//*[@id=\"mw-content-text\"]/div[1]/table/tr[2]/td/div/div/a/img";
          static NSString   *kWikipediaImageXPath7    =   @"//*[@id=\"mw-content-text\"]/div[1]/table/tr[1]/td/div/div/a/img";
          

          我在 libxml2.2 周围使用了一个名为 Hpple 的 ObjC 包装器来提取图像 url。希望这会有所帮助

          【讨论】:

            【解决方案13】:

            您也可以使用名为 SDWebImage

            的 cocoa Pod

            代码示例(记得加import SDWebImage):

            func requestInfo(flowerName: String) {
            
                    let parameters : [String:String] = [
                        "format" : "json",
                        "action" : "query",
                        "prop" : "extracts|pageimages",//pageimages allows fetch imagePath
                        "exintro" : "",
                        "explaintext" : "",
                        "titles" : flowerName,
                        "indexpageids" : "",
                        "redirects" : "1",
                        "pithumbsize" : "500"//specify image size in px
                    ]
            
            
                    AF.request(wikipediaURL, method: .get, parameters: parameters).responseJSON { (response) in
                        switch response.result {
                        case .success(let value):
                            print("Got the wikipedia info.")
                            print(response)
            
                            let flowerJSON : JSON = JSON(response.value!)
                            let pageid = flowerJSON["query"]["pageids"][0].stringValue
            
                            let flowerDescription = flowerJSON["query"]["pages"][pageid]["extract"].stringValue
            
                            let flowerImageURL = flowerJSON["query"]["pages"][pageid]["thumbnail"]["source"].stringValue //fetching Image URL
            
                            self.wikiInfoLabel.text = flowerDescription
                            self.imageView.sd_setImage(with: URL(string : flowerImageURL))//imageView updated with Wiki Image
            
                        case .failure(let error):
                            print(error)
                        }
                    }
                }
            

            【讨论】:

              【解决方案14】:

              我认为不是,但您可以使用链接解析器 HTML 文档捕获图像

              【讨论】:

              • 有什么方法可以通过API访问图片吗?
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多