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

Python脚本上传PDF至WordPress指定目录失败问题排查

问题描述

我编写了一段Python脚本,用于向WordPress上传图片和PDF文件,期望将图片上传至/wp-content/uploads/目录,PDF文件上传至/wp-content/uploads/woocommerce_uploads/目录。脚本代码如下:

import requests
import os

class UploadProductMedia:
    def __init__(self, media_endpoint, wordpress_username, wordpress_password):
        self.media_endpoint = media_endpoint
        self.wordpress_username = wordpress_username
        self.wordpress_password = wordpress_password
        pass

    def upload_media(self, file_path):
        print(f"Uploading media {file_path}")
        with open(file_path, 'rb') as file:
            # Prepare the data to send in the request
            data = {
                'file': (os.path.basename(file_path), file),
            }

            # Determine the upload directory based on the file type
            upload_directory = '/wp-content/uploads/'
            if file_path.lower().endswith(('.pdf')):
                upload_directory = '/wp-content/uploads/woocommerce_uploads/'
            print(f"Uploading to directory {upload_directory}")

            # Send a POST request to the media endpoint with authentication
            response = requests.post(f"{self.media_endpoint}?upload_to={upload_directory}", auth=(self.wordpress_username, self.wordpress_password), files=data)

            if response.status_code == 201:
                response_data = response.json()
                uploaded_media_uri = response_data.get('guid', {}).get('rendered', '')
                print(f'Successfully uploaded: {file_path}')
                return uploaded_media_uri
            else:
                print(f'Failed to upload: {file_path}')
                print(f'Response: {response.status_code} - {response.text}')
                return None


if __name__ == "__main__":
    # Example usage:
    print("=== Starting ===")
    
    for file in ["TestData\pear1.png", "TestData\pear1.pdf"]:
        UploadProductMedia('https://mysite.co.uk/wp-json/wp/v2/media', 'myusername', 'mypassword').upload_media(file)
    print("=== Finished ===")

控制台日志显示脚本执行符合预期:

=== Starting ===
Uploading media TestData\pear1.png
Uploading to directory /wp-content/uploads/
Successfully uploaded: TestData\pear1.png
Uploading media TestData\pear1.pdf
Uploading to directory /wp-content/uploads/woocommerce_uploads/
Successfully uploaded: TestData\pear1.pdf
=== Finished ===

但实际PDF文件被上传到了错误的目录,路径为https://mysite.co.uk/wp-content/uploads/2023/09/pear1.pdf,而非指定的/wp-content/uploads/woocommerce_uploads/目录。

问题原因与解决方案

原因分析

  • WordPress默认的REST API(wp/v2/media)不支持upload_to这个查询参数,你在请求中添加的?upload_to={upload_directory}会被系统直接忽略,上传路径仍遵循WordPress默认规则:按归档年月存入uploads/YYYY/MM目录。
  • /wp-content/uploads/woocommerce_uploads/是WooCommerce的专用目录,默认媒体上传接口不会识别自定义目录参数,无法直接通过URL参数指定该路径。

解决方法

方案1:通过WordPress钩子自定义上传路径

在WordPress主题的functions.php文件中添加以下代码,根据文件类型自动切换上传目录:

add_filter('upload_dir', 'custom_upload_dir_by_file_type', 10, 1);
function custom_upload_dir_by_file_type($dirs) {
    if (!empty($_FILES['file']['name'])) {
        $file_ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
        // 针对PDF文件指定woocommerce_uploads目录
        if ($file_ext === 'pdf') {
            $custom_subdir = '/woocommerce_uploads';
            $dirs['path'] = $dirs['basedir'] . $custom_subdir;
            $dirs['url'] = $dirs['baseurl'] . $custom_subdir;
            $dirs['subdir'] = $custom_subdir;
        }
    }
    return $dirs;
}

添加完成后,修改Python脚本的请求代码,去掉无效的upload_to参数:

# 原请求代码
# response = requests.post(f"{self.media_endpoint}?upload_to={upload_directory}", auth=(self.wordpress_username, self.wordpress_password), files=data)

# 修改后
response = requests.post(self.media_endpoint, auth=(self.wordpress_username, self.wordpress_password), files=data)

此时PDF文件会自动上传到woocommerce_uploads目录,图片仍走默认路径。

方案2:使用WooCommerce专用上传接口(可选)

如果上传的PDF是WooCommerce产品相关文件,可尝试使用WooCommerce的API接口,但该方式需要额外配置权限,且兼容性依赖WooCommerce版本,推荐优先使用方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:32:42