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

无法捕获UploadRobot.run()抛出的fileexists-no-change APIError求助

解决pywikibot UploadRobot无法捕获fileexists-no-change异常的问题

问题背景

使用pywikibot的UploadRobot向维基共享资源上传文件时,遇到文件已存在的场景会抛出pywikibot.exceptions.APIError: fileexists-no-change,但尝试外层try/except、post_processor回调、全局异常处理钩子均无法捕获该异常,日志显示异常被抛出后脚本仍提示“Script terminated successfully”,无法自定义处理重复文件场景。

原因分析

pywikibot的UploadRobot内部(specialbots/_upload.py的upload_file方法)已捕获APIError,仅记录日志但不会重新抛出异常,因此外层异常处理机制无法感知;同时post_processor的触发逻辑未覆盖fileexists-no-change这类场景,导致回调无法生效。

解决方案

方法一:上传前预检查文件是否存在

在调用UploadRobot前,先构造FilePage对象检查目标文件是否已存在,提前处理重复场景:

import sys
import pywikibot
from pywikibot.specialbots import UploadRobot

# 初始化维基共享资源站点
site = pywikibot.Site('commons', 'commons')

def check_file_exists(target_filename):
    """检查目标文件是否已存在于维基共享资源"""
    file_page = pywikibot.FilePage(site, target_filename)
    return file_page.exists()

# 提取本地文件的目标文件名(根据实际路径调整)
local_file_path = sys.argv[1]
target_filename = local_file_path.split('/')[-1]

# 预检查逻辑
if check_file_exists(target_filename):
    print(f"⚠️ 文件 {target_filename} 已存在,跳过上传")
else:
    # 初始化UploadRobot并执行上传
    bot = UploadRobot(
        local_file_path,
        description=description,
        keep_filename=True,
        ignore_warning=True,
        target_site=site,
        summary=summary,
        always=True
    )
    bot.run()

方法二:子类化UploadRobot,重写异常处理逻辑

通过继承UploadRobot,重写upload_file方法,自定义捕获fileexists-no-change异常的处理逻辑:

import sys
import pywikibot
from pywikibot.specialbots import UploadRobot
from pywikibot.exceptions import APIError

class CustomUploadRobot(UploadRobot):
    def upload_file(self, file_url, title=None):
        try:
            # 调用父类的上传逻辑
            return super().upload_file(file_url, title)
        except APIError as e:
            if e.code == 'fileexists-no-change':
                # 自定义重复文件的处理逻辑
                print(f"⚠️ 上传失败:文件已存在 - {e}")
                return None  # 返回None可触发post_processor的失败分支
            else:
                # 其他API异常原样抛出,由外层处理
                raise

# 使用自定义机器人执行上传
bot = CustomUploadRobot(
    sys.argv[1],
    description=description,
    keep_filename=True,
    ignore_warning=True,
    target_site=pywikibot.Site('commons', 'commons'),
    summary=summary,
    always=True,
    post_processor=lambda file_url, filename: print(f"✅ 上传成功: {filename}" if filename else f"⚠️ 处理失败: {file_url}")
)

try:
    bot.run()
except APIError as e:
    print(f"未处理的API错误: {e}")

方法三:监听pywikibot日志消息

利用pywikibot的日志系统,捕获包含fileexists-no-change的日志输出,实现自定义处理:

import logging
import sys
import pywikibot
from pywikibot.specialbots import UploadRobot

# 自定义日志处理器
class DuplicateFileHandler(logging.Handler):
    def emit(self, record):
        if 'fileexists-no-change' in record.getMessage():
            print(f"⚠️ 检测到重复文件: {record.getMessage()}")

# 添加处理器到pywikibot的日志器
logger = logging.getLogger('pywikibot')
logger.addHandler(DuplicateFileHandler())

# 初始化并运行UploadRobot
bot = UploadRobot(
    sys.argv[1],
    description=description,
    keep_filename=True,
    ignore_warning=True,
    target_site=pywikibot.Site('commons', 'commons'),
    summary=summary,
    always=True
)
bot.run()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:44:56