374 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
#!/usr/bin/env python3
 | 
						|
# -*- coding: utf-8 -*-
 | 
						|
"""
 | 
						|
WordPress REST API 使用示例
 | 
						|
演示常见的WordPress操作
 | 
						|
"""
 | 
						|
 | 
						|
import os
 | 
						|
import requests
 | 
						|
import json
 | 
						|
from requests.auth import HTTPBasicAuth
 | 
						|
from datetime import datetime
 | 
						|
from dotenv import load_dotenv
 | 
						|
 | 
						|
# 加载环境变量
 | 
						|
load_dotenv()
 | 
						|
 | 
						|
# WordPress 配置信息
 | 
						|
WP_URL = os.getenv('WORDPRESS_URL')
 | 
						|
WP_USER = os.getenv('WORDPRESS_USERNAME')
 | 
						|
WP_APP_PASSWORD = os.getenv('WORDPRESS_APP_PASSWORD')
 | 
						|
 | 
						|
# 移除密码中的空格
 | 
						|
if WP_APP_PASSWORD:
 | 
						|
    WP_APP_PASSWORD = WP_APP_PASSWORD.replace(" ", "")
 | 
						|
 | 
						|
# 检查必需的环境变量
 | 
						|
if not all([WP_URL, WP_USER, WP_APP_PASSWORD]):
 | 
						|
    print("❌ 错误: 请在 .env 文件中配置 WORDPRESS_URL, WORDPRESS_USERNAME, WORDPRESS_APP_PASSWORD")
 | 
						|
    exit(1)
 | 
						|
 | 
						|
class WordPressAPI:
 | 
						|
    def __init__(self, url, username, app_password):
 | 
						|
        self.base_url = url.rstrip('/')
 | 
						|
        self.api_url = f"{self.base_url}/wp-json/wp/v2"
 | 
						|
        self.username = username
 | 
						|
        self.app_password = app_password
 | 
						|
        self.auth = HTTPBasicAuth(username, app_password)
 | 
						|
        
 | 
						|
    def get_posts(self, per_page=10, status='publish'):
 | 
						|
        """获取文章列表"""
 | 
						|
        params = {
 | 
						|
            'per_page': per_page,
 | 
						|
            'status': status
 | 
						|
        }
 | 
						|
        response = requests.get(f"{self.api_url}/posts", params=params)
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"获取文章失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def get_post_by_id(self, post_id):
 | 
						|
        """根据ID获取特定文章"""
 | 
						|
        response = requests.get(f"{self.api_url}/posts/{post_id}")
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"获取文章失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def create_post(self, title, content, status='draft', categories=None, tags=None):
 | 
						|
        """创建新文章"""
 | 
						|
        post_data = {
 | 
						|
            'title': title,
 | 
						|
            'content': content,
 | 
						|
            'status': status
 | 
						|
        }
 | 
						|
        
 | 
						|
        if categories:
 | 
						|
            post_data['categories'] = categories
 | 
						|
        if tags:
 | 
						|
            post_data['tags'] = tags
 | 
						|
            
 | 
						|
        response = requests.post(
 | 
						|
            f"{self.api_url}/posts",
 | 
						|
            json=post_data,
 | 
						|
            auth=self.auth
 | 
						|
        )
 | 
						|
        
 | 
						|
        if response.status_code == 201:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"创建文章失败: {response.status_code}")
 | 
						|
            print(response.text)
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def update_post(self, post_id, title=None, content=None, status=None):
 | 
						|
        """更新文章"""
 | 
						|
        update_data = {}
 | 
						|
        if title:
 | 
						|
            update_data['title'] = title
 | 
						|
        if content:
 | 
						|
            update_data['content'] = content
 | 
						|
        if status:
 | 
						|
            update_data['status'] = status
 | 
						|
            
 | 
						|
        response = requests.post(
 | 
						|
            f"{self.api_url}/posts/{post_id}",
 | 
						|
            json=update_data,
 | 
						|
            auth=self.auth
 | 
						|
        )
 | 
						|
        
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"更新文章失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def delete_post(self, post_id, force=False):
 | 
						|
        """删除文章"""
 | 
						|
        params = {'force': 'true'} if force else {}
 | 
						|
        response = requests.delete(
 | 
						|
            f"{self.api_url}/posts/{post_id}",
 | 
						|
            params=params,
 | 
						|
            auth=self.auth
 | 
						|
        )
 | 
						|
        
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"删除文章失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def get_categories(self):
 | 
						|
        """获取分类列表"""
 | 
						|
        response = requests.get(f"{self.api_url}/categories")
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"获取分类失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def create_category(self, name, description="", parent=0):
 | 
						|
        """创建新分类"""
 | 
						|
        category_data = {
 | 
						|
            'name': name,
 | 
						|
            'description': description,
 | 
						|
            'parent': parent
 | 
						|
        }
 | 
						|
        
 | 
						|
        response = requests.post(
 | 
						|
            f"{self.api_url}/categories",
 | 
						|
            json=category_data,
 | 
						|
            auth=self.auth
 | 
						|
        )
 | 
						|
        
 | 
						|
        if response.status_code == 201:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"创建分类失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def get_tags(self):
 | 
						|
        """获取标签列表"""
 | 
						|
        response = requests.get(f"{self.api_url}/tags")
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"获取标签失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def create_tag(self, name, description=""):
 | 
						|
        """创建新标签"""
 | 
						|
        tag_data = {
 | 
						|
            'name': name,
 | 
						|
            'description': description
 | 
						|
        }
 | 
						|
        
 | 
						|
        response = requests.post(
 | 
						|
            f"{self.api_url}/tags",
 | 
						|
            json=tag_data,
 | 
						|
            auth=self.auth
 | 
						|
        )
 | 
						|
        
 | 
						|
        if response.status_code == 201:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"创建标签失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def upload_media(self, file_path, title=None, alt_text=None):
 | 
						|
        """上传媒体文件"""
 | 
						|
        if not os.path.exists(file_path):
 | 
						|
            print(f"文件不存在: {file_path}")
 | 
						|
            return None
 | 
						|
            
 | 
						|
        filename = os.path.basename(file_path)
 | 
						|
        
 | 
						|
        with open(file_path, 'rb') as f:
 | 
						|
            files = {
 | 
						|
                'file': (filename, f, 'application/octet-stream')
 | 
						|
            }
 | 
						|
            
 | 
						|
            data = {}
 | 
						|
            if title:
 | 
						|
                data['title'] = title
 | 
						|
            if alt_text:
 | 
						|
                data['alt_text'] = alt_text
 | 
						|
                
 | 
						|
            response = requests.post(
 | 
						|
                f"{self.api_url}/media",
 | 
						|
                files=files,
 | 
						|
                data=data,
 | 
						|
                auth=self.auth
 | 
						|
            )
 | 
						|
            
 | 
						|
            if response.status_code == 201:
 | 
						|
                return response.json()
 | 
						|
            else:
 | 
						|
                print(f"上传媒体失败: {response.status_code}")
 | 
						|
                return None
 | 
						|
    
 | 
						|
    def get_media(self, per_page=10):
 | 
						|
        """获取媒体列表"""
 | 
						|
        params = {'per_page': per_page}
 | 
						|
        response = requests.get(f"{self.api_url}/media", params=params)
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"获取媒体失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
    
 | 
						|
    def search_posts(self, search_term, per_page=10):
 | 
						|
        """搜索文章"""
 | 
						|
        params = {
 | 
						|
            'search': search_term,
 | 
						|
            'per_page': per_page
 | 
						|
        }
 | 
						|
        response = requests.get(f"{self.api_url}/posts", params=params)
 | 
						|
        if response.status_code == 200:
 | 
						|
            return response.json()
 | 
						|
        else:
 | 
						|
            print(f"搜索文章失败: {response.status_code}")
 | 
						|
            return None
 | 
						|
 | 
						|
def demo_basic_operations():
 | 
						|
    """演示基本操作"""
 | 
						|
    print("🚀 WordPress REST API 基本操作演示\n")
 | 
						|
    
 | 
						|
    wp = WordPressAPI(WP_URL, WP_USER, WP_APP_PASSWORD)
 | 
						|
    
 | 
						|
    # 1. 获取现有文章
 | 
						|
    print("📝 获取现有文章...")
 | 
						|
    posts = wp.get_posts(per_page=5)
 | 
						|
    if posts:
 | 
						|
        print(f"找到 {len(posts)} 篇文章:")
 | 
						|
        for post in posts:
 | 
						|
            print(f"  - {post['title']['rendered']} (ID: {post['id']})")
 | 
						|
    else:
 | 
						|
        print("没有找到文章")
 | 
						|
    
 | 
						|
    # 2. 获取分类
 | 
						|
    print("\n📂 获取分类...")
 | 
						|
    categories = wp.get_categories()
 | 
						|
    if categories:
 | 
						|
        print(f"找到 {len(categories)} 个分类:")
 | 
						|
        for cat in categories:
 | 
						|
            print(f"  - {cat['name']} (ID: {cat['id']}, 文章数: {cat['count']})")
 | 
						|
    
 | 
						|
    # 3. 获取标签
 | 
						|
    print("\n🏷️ 获取标签...")
 | 
						|
    tags = wp.get_tags()
 | 
						|
    if tags:
 | 
						|
        print(f"找到 {len(tags)} 个标签:")
 | 
						|
        for tag in tags[:5]:  # 只显示前5个
 | 
						|
            print(f"  - {tag['name']} (ID: {tag['id']}, 使用次数: {tag['count']})")
 | 
						|
    else:
 | 
						|
        print("没有找到标签")
 | 
						|
    
 | 
						|
    # 4. 获取媒体文件
 | 
						|
    print("\n🖼️ 获取媒体文件...")
 | 
						|
    media = wp.get_media(per_page=5)
 | 
						|
    if media:
 | 
						|
        print(f"找到 {len(media)} 个媒体文件:")
 | 
						|
        for item in media:
 | 
						|
            print(f"  - {item['title']['rendered']} (类型: {item['media_type']})")
 | 
						|
    
 | 
						|
    print("\n✅ 基本操作演示完成!")
 | 
						|
 | 
						|
def demo_create_content():
 | 
						|
    """演示内容创建"""
 | 
						|
    print("\n🎨 WordPress 内容创建演示\n")
 | 
						|
    
 | 
						|
    wp = WordPressAPI(WP_URL, WP_USER, WP_APP_PASSWORD)
 | 
						|
    
 | 
						|
    # 创建测试分类
 | 
						|
    print("📂 创建测试分类...")
 | 
						|
    test_category = wp.create_category(
 | 
						|
        name="API测试分类",
 | 
						|
        description="这是通过API创建的测试分类"
 | 
						|
    )
 | 
						|
    
 | 
						|
    if test_category:
 | 
						|
        category_id = test_category['id']
 | 
						|
        print(f"✅ 分类创建成功 (ID: {category_id})")
 | 
						|
        
 | 
						|
        # 创建测试标签
 | 
						|
        print("\n🏷️ 创建测试标签...")
 | 
						|
        test_tag = wp.create_tag(
 | 
						|
            name="API测试",
 | 
						|
            description="API测试标签"
 | 
						|
        )
 | 
						|
        
 | 
						|
        if test_tag:
 | 
						|
            tag_id = test_tag['id']
 | 
						|
            print(f"✅ 标签创建成功 (ID: {tag_id})")
 | 
						|
            
 | 
						|
            # 创建测试文章
 | 
						|
            print("\n📝 创建测试文章...")
 | 
						|
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 | 
						|
            test_post = wp.create_post(
 | 
						|
                title=f"API测试文章 - {current_time}",
 | 
						|
                content=f"""
 | 
						|
                <h2>这是通过WordPress REST API创建的测试文章</h2>
 | 
						|
                <p>创建时间: {current_time}</p>
 | 
						|
                <p>这篇文章演示了如何使用WordPress REST API进行内容管理:</p>
 | 
						|
                <ul>
 | 
						|
                    <li>创建文章</li>
 | 
						|
                    <li>设置分类和标签</li>
 | 
						|
                    <li>使用HTML格式的内容</li>
 | 
						|
                </ul>
 | 
						|
                <p><strong>注意:</strong> 这是一个测试文章,可以安全删除。</p>
 | 
						|
                """,
 | 
						|
                status='draft',  # 草稿状态
 | 
						|
                categories=[category_id],
 | 
						|
                tags=[tag_id]
 | 
						|
            )
 | 
						|
            
 | 
						|
            if test_post:
 | 
						|
                post_id = test_post['id']
 | 
						|
                print(f"✅ 文章创建成功 (ID: {post_id})")
 | 
						|
                print(f"   标题: {test_post['title']['rendered']}")
 | 
						|
                print(f"   状态: {test_post['status']}")
 | 
						|
                print(f"   链接: {test_post['link']}")
 | 
						|
                
 | 
						|
                # 询问是否删除测试内容
 | 
						|
                print("\n🗑️ 清理测试内容...")
 | 
						|
                
 | 
						|
                # 删除测试文章
 | 
						|
                if wp.delete_post(post_id, force=True):
 | 
						|
                    print(f"✅ 测试文章已删除 (ID: {post_id})")
 | 
						|
                
 | 
						|
                # 删除测试分类和标签需要小心,因为可能有其他内容在使用
 | 
						|
                print("⚠️ 测试分类和标签保留,请手动删除如果不需要")
 | 
						|
                
 | 
						|
            else:
 | 
						|
                print("❌ 文章创建失败")
 | 
						|
        else:
 | 
						|
            print("❌ 标签创建失败")
 | 
						|
    else:
 | 
						|
        print("❌ 分类创建失败")
 | 
						|
    
 | 
						|
    print("\n✅ 内容创建演示完成!")
 | 
						|
 | 
						|
def main():
 | 
						|
    """主函数"""
 | 
						|
    print("WordPress REST API 使用示例")
 | 
						|
    print("=" * 40)
 | 
						|
    
 | 
						|
    # 基本操作演示
 | 
						|
    demo_basic_operations()
 | 
						|
    
 | 
						|
    # 内容创建演示
 | 
						|
    demo_create_content()
 | 
						|
    
 | 
						|
    print("\n🎉 所有演示完成!")
 | 
						|
    print("\n💡 提示:")
 | 
						|
    print("- 所有创建的测试内容都已清理")
 | 
						|
    print("- 你可以修改这个脚本来适应你的具体需求")
 | 
						|
    print("- 更多API文档: https://developer.wordpress.org/rest-api/")
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main() |