WordPress 대시보드에서 글을 하나씩 삭제하다 보면 한계가 금방 옵니다. 50개, 100개가 넘어가는 순간 수작업은 현실적으로 불가능합니다. WordPress REST API와 Python을 조합하면 이 작업을 스크립트 한 번 실행으로 끝낼 수 있습니다.
WordPress REST API로 글 일괄 휴지통 이동이 가능한 이유

WordPress REST API(워드프레스가 외부 프로그램과 데이터를 주고받을 수 있도록 제공하는 인터페이스)는 기본적으로 글의 상태를 변경하는 기능을 지원합니다. 게시글 상태를 trash로 변경하면 대시보드에서 삭제 버튼을 누른 것과 동일한 결과가 됩니다.
Python에서 requests 라이브러리를 사용하면 이 API를 반복 호출하는 방식으로 여러 글을 순서대로 처리할 수 있습니다. 별도 플러그인 없이 WordPress 기본 기능만으로 동작하기 때문에 환경 의존성이 낮습니다.
사전 준비 — 인증 방식과 필요한 정보
API를 호출하려면 인증이 필요합니다. 가장 간단한 방법은 Application Password(애플리케이션 비밀번호)를 사용하는 것입니다. WordPress 5.6 이상에서 기본 지원하며, 설정 경로는 다음과 같습니다.
- WordPress 관리자 → 사용자 → 프로필
- 하단 ‘애플리케이션 비밀번호’ 섹션에서 이름 입력 후 생성
- 생성된 비밀번호를 복사해 별도 저장 (창을 닫으면 다시 볼 수 없습니다)
스크립트 실행에 필요한 정보는 세 가지입니다.
- 사이트 도메인:
https://example.com - WordPress 관리자 계정 아이디
- 위에서 생성한 애플리케이션 비밀번호
WordPress 프로필 페이지에서 애플리케이션 비밀번호 생성
Python 스크립트 전체 구조
스크립트는 크게 두 단계로 동작합니다. 먼저 삭제 대상 글 목록을 가져오고, 이후 각 글의 상태를 trash로 변경합니다.
import requests
from requests.auth import HTTPBasicAuth
# 설정값
SITE_URL = "https://example.com" # 실제 사이트 주소로 변경
USERNAME = "admin" # WordPress 관리자 아이디
APP_PASSWORD = "xxxx xxxx xxxx" # 애플리케이션 비밀번호
auth = HTTPBasicAuth(USERNAME, APP_PASSWORD)
headers = {"Content-Type": "application/json"}
def get_all_posts(status="publish"):
posts = []
page = 1
while True:
url = f"{SITE_URL}/wp-json/wp/v2/posts"
params = {"status": status, "per_page": 100, "page": page}
response = requests.get(url, auth=auth, params=params)
if response.status_code != 200 or not response.json():
break
posts.extend(response.json())
page += 1
return posts
def trash_post(post_id):
url = f"{SITE_URL}/wp-json/wp/v2/posts/{post_id}"
response = requests.post(url, auth=auth, headers=headers,
json={"status": "trash"})
return response.status_code
if __name__ == "__main__":
posts = get_all_posts(status="publish")
print(f"대상 글 수: {len(posts)}개")
for post in posts:
code = trash_post(post["id"])
print(f" ID {post['id']} — 상태 코드 {code}")
print("완료")
per_page 값을 100으로 설정하면 API 호출 1회당 최대 100개까지 가져옵니다. 글 수가 100개를 초과할 경우 while 루프가 페이지를 자동으로 넘기며 전체 목록을 수집합니다.
조건 필터링 — 특정 카테고리나 날짜 범위만 선택하는 방법
전체 글이 아니라 특정 조건에 해당하는 글만 휴지통으로 이동하려면 get_all_posts 함수의 params에 필터를 추가합니다.
| 조건 | 파라미터 예시 | 설명 |
|---|---|---|
| 특정 카테고리 | "categories": 5 |
카테고리 ID로 필터 (숫자) |
| 특정 날짜 이전 | "before": "2024-01-01T00:00:00" |
ISO 8601 형식 |
| 특정 날짜 이후 | "after": "2023-01-01T00:00:00" |
ISO 8601 형식 |
| 작성자 기준 | "author": 1 |
사용자 ID로 필터 |
카테고리 ID는 WordPress 관리자 → 글 → 카테고리 메뉴에서 해당 카테고리를 클릭하면 URL에 tag_ID=숫자 형태로 확인할 수 있습니다.
카테고리 편집 URL에서 ID 확인
실행 전 반드시 확인해야 할 주의사항
스크립트를 실행하기 전에 아래 세 가지를 점검합니다.
- HTTPS 환경 필수 — HTTP 사이트에서는 Basic 인증 자격 정보가 평문으로 전송됩니다. 반드시 SSL이 적용된 환경에서 실행합니다.
- 소량 테스트 먼저 — 처음 실행 시
posts리스트를 슬라이싱해서posts[:3]처럼 3개만 먼저 처리해 보는 것이 안전합니다. 휴지통 이동은 영구 삭제가 아니므로 복구는 가능하지만, 대량 처리 후 복구는 번거롭습니다. - 403 오류 발생 시 — 계정 권한이 편집자(Editor) 이하인 경우 다른 사용자의 글을 수정할 수 없습니다. 관리자(Administrator) 계정으로 실행하거나, 본인 소유 글만 처리 대상으로 제한합니다.
WordPress REST API 글 일괄 처리 — 활용 범위
같은 구조로 글 상태를 trash 외에 draft(임시저장)나 private(비공개)으로도 변경할 수 있습니다. 휴지통 이동 외에도 특정 카테고리 전체를 비공개로 전환하거나, 오래된 글을 일괄 초안 상태로 되돌리는 데 동일한 스크립트 구조를 재사용할 수 있습니다.
WordPress REST API 공식 문서는 WordPress REST API Handbook에서 확인할 수 있습니다. 지원하는 파라미터 전체 목록과 응답 형식이 정리되어 있습니다.
자주 묻는 질문
Q. 휴지통으로 이동한 글은 자동으로 영구 삭제됩니까?
WordPress 기본 설정에서는 휴지통 이동 후 30일이 지나면 자동으로 영구 삭제됩니다. 설정 → 읽기에서 이 주기를 조정할 수 있습니다.
Q. 페이지(Pages)도 같은 방식으로 처리할 수 있습니까?
가능합니다. API 엔드포인트를 /wp-json/wp/v2/posts에서 /wp-json/wp/v2/pages로 변경하면 동일하게 동작합니다.
Q. 애플리케이션 비밀번호가 보이지 않으면 어떻게 합니까?
WordPress 5.6 미만이거나 일부 보안 플러그인이 해당 기능을 비활성화한 경우입니다. 플러그인 충돌 여부를 먼저 확인하고, 버전이 낮다면 업그레이드를 검토합니다.
스크립트 자체는 단순합니다. 복잡해 보이는 부분은 인증 설정인데, 애플리케이션 비밀번호를 한 번 만들어 두면 이후 API 활용 범위가 꽤 넓어집니다.
썸네일: Stephen Phillips – Hostreviews.co.uk on Unsplash