You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Wikimedia Commons获取全部图片文件名?

问题

我尝试通过Wikimedia Commons图像搜索获取所有图片文件名,但仅得到10条结果。示例代码如下:

import json
from io import StringIO
import pandas as pd
import numpy as np
import cv2
import matplotlib.pyplot as plt
import urllib.request
import requests
import time
import shutil
from bs4 import BeautifulSoup
from newspaper import Article
import sys
import html2text
import xmltodict
from xml.etree import ElementTree
import urllib

headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
plants_df = pd.DataFrame()
pic_searches = ['blue+marble']
df_all = pd.DataFrame()
for pic_search in pic_searches:
    url = str(r'https://commons.wikimedia.org/w/api.php?action=query&prop=imageinfo|categories&+\   generator=search&gsrsearch=File:') + str(pic_search) + str('&format=jsonfm&origin=*&   + \ iiprop=extmetadata&iiextmetadatafilter=ImageDescription|ObjectName') + \
    response = urllib.request.urlopen(url).read()
    soup = BeautifulSoup(response, 'html.parser')
    spans = soup.find_all('span', {'class': 's2'})
    lines = [span.get_text() for span in spans]
    new_list = [item.replace('"', '') for item in lines]
    new_list2 = [x for x in new_list if x.startswith('File')]
    new_list3 = [x[5:] for x in new_list2]
    new_list4 = [x.replace(' ','_') for x in new_list3]
    print(new_list4)

运行后仅返回10个文件名:
['Blue_Marble_2021.png', 'Blue_Marble_2022.jpg', 'Blue_Marble_Comparsion.png', 'Blue_Marble_Eastern_Hemisphere.jpg', 'Blue_Marble_Western_Hemisphere.jpg', 'Blue_Marble_transparent.png', 'The_Blue_Marble.jpg', 'The_Blue_Marble_(5052124705).jpg', 'The_Blue_Marble_White_Balancing.jpg', 'The_Earth_seen_from_Apollo_17.jpg']
但在Wikimedia Commons网页搜索“blue marble”能得到数百条结果,如何获取全部图片文件名?

解决方案

1. 核心问题分析

你的代码只返回10条结果,原因有两个:

  • 默认情况下Wikimedia API单次返回结果上限是10条,未设置gsrlimit参数调整数量;
  • 使用了format=jsonfm(网页格式化输出),只能解析当前页的10条,没有处理分页逻辑。

2. 修正后的实现代码

直接调用API的JSON格式接口,通过分页机制获取所有结果:

import requests
import time

def fetch_all_image_names(search_query):
    base_url = "https://commons.wikimedia.org/w/api.php"
    params = {
        "action": "query",
        "generator": "search",
        "gsrsearch": f"File:{search_query}",
        "gsrnamespace": 6,  # 限定为文件命名空间,只返回图片
        "gsrlimit": 500,    # 单次请求最大返回数(API上限为500)
        "prop": "imageinfo",
        "iiprop": "extmetadata",
        "iiextmetadatafilter": "ObjectName",
        "format": "json",
        "origin": "*"
    }
    
    all_images = []
    
    while True:
        resp = requests.get(base_url, params=params)
        data = resp.json()
        
        # 提取当前页的图片名称
        if "query" in data and "pages" in data["query"]:
            for page in data["query"]["pages"].values():
                if "title" in page:
                    img_name = page["title"][5:].replace(" ", "_")
                    all_images.append(img_name)
        
        # 检查是否还有下一页
        if "continue" not in data:
            break
        
        # 更新参数,获取下一页数据
        params.update(data["continue"])
        time.sleep(1)  # 控制请求频率,避免触发API限制
    
    return all_images

# 调用函数获取所有"blue marble"相关图片
image_list = fetch_all_image_names("blue marble")
print(f"共获取到{len(image_list)}张图片")
print(image_list[:10])  # 打印前10条示例

关键优化点

  • 改用format=json:直接解析JSON数据,无需BeautifulSoup处理网页,更高效准确;
  • 设置gsrlimit=500:单次请求获取最多500条结果,减少请求次数;
  • 处理分页continue参数:API返回continue时,携带该参数发起下一次请求,直到获取所有结果;
  • 限定gsrnamespace=6:确保只返回文件(图片)类型的结果,排除无关内容;
  • 添加请求延迟:time.sleep(1)避免请求过于频繁,防止被API封禁。

内容的提问来源于stack exchange,提问作者beardedgardener

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:02:00