머리말
워드프레스는 내가 특별히 무언가를 하지 않아도 기본적으로 Rest API 를 제공한다. 우리는 워드프레스 자동 등록 기능 구현을 위해 이 Rest API 이라는 녀석을 사용하게 될 것이다.
이번 포스팅에서는 이 워드프레스 Rest API 를 이용하여 글 등록하는 부분을 우선 구현 해보고자 한다.
참고용 강의 자료 소스
Summary
- 워드프레스 Rest API 사용법
- JWT 인증 토큰 생성 및 쓰기 권한 얻기
- 워드프레스 새 글 생성
코드의 기본 구조
구체적인 코드 작성에 앞서서 전체적인 코드의 구성을 알 필요가 있다. 물론 최종 편에서는 이 구조도 좀 더 변경이 되겠지만 아래 소스와 같다.
- ChatGPT 컨텐츠 생성 함수
- 워드프레스 포스팅 함수
이렇게 ChatGPT 에서 할 일과 워드프레스 Rest API 에서 할 일 두가지를 각각 별도의 함수로 만들어 두고 페이지 가장 하단 “메인 프로세스” 에서 컨트롤 할 것이다.
이 구조를 머리에 잘 담아두고 파이썬 코드를 작성 해보도록 하자.
import requests, openai
from bs4 import BeautifulSoup
from time import sleep
# ChatGPT 컨텐츠 생성 함수
def generateChatGPT():
pass
# 워드프레스 자동 포스팅 함수
def createPost():
pass
"""
메인 프로세스
"""
if __name__ == "__main__":
# ChatGPT 새 글 생성
generateChatGPT()
# 워드프레스 자동 포스팅
createPost()
워드프레스 Rest API 포스트
워드프레스 Rest API: Post 편 공식문서
워드프레스 글 작성 기본 문법
Rest API의 Post 편 공식 문서 를 참고 해보면,
POST /wp/v2/posts
POST 방식으로 호출 하고 호출 URL 은 /wp/v2/posts 이라고 명시되어 있다.
# 워드프레스 자동 포스팅 함수
def createPost():
# 워드프레스 포스팅 데이터 설정
postURL = "https://ecat.kr/wp-json/wp/v2/posts"
postData = {
}
# 워드프레스 포스팅 생성 요청 보내기
response = requests.post(postURL, json=postData)
우리는 requests 모듈을 이용해서 호출 할 것이고 Rest API 문서에서 POST 방식으로 호출 하라고 했으니
requests.post(호출 URL, json={파라미터})
참고로 호출 URL 같은 경우는 브라우저에 직접 입력 해봤을때 포스팅 데이터들이 주루룩 나와야 Rest API 가 정상 작동하고 있는 것이다.
위 화면은 필자와 좀 다르게 나올 수도 있다. 크롬이나 엣지 확장 프로그램중 JSONViewer 라는 것을 설치 해놔서 저렇게 이쁘게 나오는 것 뿐이다.
그렇다면 새 글 작성시 어떤 내용들을 담아서 보낼까?
Rest API의 Post 편 공식 문서 에서 Arguments 를 보면 상당히 많은데 이 중에서 글 작성시 필요한 최소한의 것 몇 가지만 사용해보자.
postData = {
'title': "글 제목 입니다.",
'slug': "글 제목 입니다.".replace(' ', '-'),
'content': "본문 내용 입니다.",
'meta': {
'category': "여행"
},
'status': 'draft'
}
글 제목, 슬러그, 본문내용, 카테고리, 공개여부(임시저장: draft / 바로 발행: publish)
슬러그는 공백을 하이픈(-) 으로 변경해주어 공백없는 문자열로 만들어준다. 이런 json 형태로 데이터를 작성 해준 후에 파라미터 전달을 해주면 끝이다.
다음의 코드를 실행해보자.
import requests, openai
from bs4 import BeautifulSoup
from time import sleep
# 워드프레스 자동 포스팅 함수
def createPost():
# 워드프레스 포스팅 데이터 설정
postURL = "https://ecat.kr/wp-json/wp/v2/posts"
postData = {
'title': "글 제목 입니다.",
'slug': "글 제목 입니다.".replace(' ', '-'),
'content': "본문 내용 입니다.",
'meta': {
'category': "여행"
},
'status': 'draft'
}
# 워드프레스 포스팅 생성 요청 보내기
response = requests.post(postURL, json=postData)
print(response.text)
exit()
"""
메인 프로세스
"""
if __name__ == "__main__":
# 워드프레스 자동 포스팅
createPost()
어라? 특별히 문제가 없어 보이는데 등록이 되지 않고 에러 메세지가 나온다.
{"code":"rest_cannot_create","message":"\uc8c4\uc1a1\ud569\ub2c8\ub2e4. \uc774 \uc0ac\uc6a9\uc790\ub85c\uc368 \uae00\uc744 \uc791\uc131\ud558\ub3c4\ub85d \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.","data":{"status":401}}
이렇게 유니코드로 나오는데 변환을 해보면,
{
"code": "rest_cannot_create",
"message": "죄송합니다. 이 사용자로써 글을 작성하도록 허용하지 않았습니다.",
"data": {
"status": 401
}
}
즉, 글을 작성 하려고 하는데 글 작성 권한이 없다는 내용이다.
이 인증을 받기 위해서는 지난 포스팅에서 사전 준비 해뒀던 JWT 를 이용하여 토큰을 부여 받아서 쓰기 권한을 받고 글을 작성 할 것이다.
VS Code 추천 플러그인: vscode-json
JSON 자동 정렬 및 유니코드를 한글로 자동 변환
JWT 인증 토큰 얻기
JWT Authentication for WP-API 플러그인을 이용하여 토큰을 얻어보자. 사용법은 다음과 같다.
# 워드프레스 JWT 인증 토큰 얻기
url = "https://ecat.kr/wp-json/jwt-auth/v1/token"
data = {
'username':'워드프레스 아이디',
'password':'워드프레스 비밀번호'
}
res = requests.post(url, data=data).json()
token = res.get('token')
print(token)
exit()
위의 코드에 본인의 워드프레스 아이디, 비밀번호를 입력하고 실행 시켜 보자.
정상적으로 로그인이 되었다면 이렇게 뭐라고 꿍시렁 꿍시렁 알아보지 못할 긴 문자열이 나온다. 이것이 인증 토큰이다.
서버에서 알아서 생성 해준 것이므로 뭔 뜻인지 알 필요는 없고 그냥 잘 작동 하는구나.. 하고 넘어가면 된다.
이렇게 얻은 인증 토큰 값을 Header 에 값을 실어서 보내면 쓰기 권한을 얻게된 상태가 되며 Header에 실어보낼 형태는 다음과 같다.
'Authorization': 'Bearer 토큰 값'
# 워드프레스 JWT 인증 토큰 얻기
url = "https://ecat.kr/wp-json/jwt-auth/v1/token"
data = {
'username':'워드프레스 아이디',
'password':'워드프레스 비밀번호'
}
res = requests.post(url, data=data).json()
token = res.get('token')
# 헤더에 JWT 인증 토큰 데이터 추가
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {token}'
}
JWT 인증 포함 워드프레스 새 글 생성
JWT 토큰 값은 얻었으므로 Rest API 쪽에도 header 값 실어 보낼 부분을 다음과 같이 추가해준다.
# 워드프레스 포스팅 생성 요청 보내기
response = requests.post(postURL, json=postData, headers=headers)
실행 코드
import requests, openai
from bs4 import BeautifulSoup
from time import sleep
# 워드프레스 자동 포스팅 함수
def createPost():
# 워드프레스 JWT 인증 토큰 얻기
url = "https://ecat.kr/wp-json/jwt-auth/v1/token"
data = {
'username':'워드프레스 아이디',
'password':'워드프레스 비밀번호'
}
res = requests.post(url, data=data).json()
token = res.get('token')
# 헤더에 JWT 인증 토큰 데이터 추가
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {token}'
}
# 워드프레스 포스팅 데이터 설정
postURL = "https://ecat.kr/wp-json/wp/v2/posts"
postData = {
'title': "글 제목 입니다.",
'slug': "글 제목 입니다.".replace(' ', '-'),
'content': "본문 내용 입니다.",
'meta': {
'category': "여행"
},
'status': 'draft'
}
# 워드프레스 포스팅 생성 요청 보내기
response = requests.post(postURL, json=postData, headers=headers)
print(response.text)
exit()
"""
메인 프로세스
"""
if __name__ == "__main__":
# 워드프레스 자동 포스팅
createPost()
실행 결과
{
"id": 916,
"date": "2023-07-29T08:03:47",
"date_gmt": "2023-07-28T23:03:47",
"guid": {
"rendered": "https://ecat.kr/?p=916",
"raw": "https://ecat.kr/?p=916"
},
"modified": "2023-07-29T08:03:47",
"modified_gmt": "2023-07-28T23:03:47",
"password": "",
"slug": "%ea%b8%80-%ec%a0%9c%eb%aa%a9-%ec%9e%85%eb%8b%88%eb%8b%a4-3",
"status": "draft",
"type": "post",
"link": "https://ecat.kr/?p=916",
"title": {
"raw": "글 제목 입니다.",
"rendered": "글 제목 입니다."
},
"content": {
"raw": "본문 내용 입니다.",
"rendered": "<p>본문 내용 입니다.</p>\n",
"protected": false,
"block_version": 0
},
"excerpt": {
"raw": "",
"rendered": "<p>본문 내용 입니다.</p>\n",
"protected": false
},
"author": 2,
"featured_media": 0,
"comment_status": "open",
"ping_status": "open",
"sticky": false,
"template": "",
"format": "standard",
"meta": [],
"categories": [
1
],
"tags": [],
"permalink_template": "https://ecat.kr/%postname%/",
"generated_slug": "글-제목-입니다-3",
"jetpack_featured_media_url": "",
"_links": {
"self": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"collection": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts"
}
],
"about": [
{
"href": "https://ecat.kr/wp-json/wp/v2/types/post"
}
],
"author": [
{
"embeddable": true,
"href": "https://ecat.kr/wp-json/wp/v2/users/2"
}
],
"replies": [
{
"embeddable": true,
"href": "https://ecat.kr/wp-json/wp/v2/comments?post=916"
}
],
"version-history": [
{
"count": 0,
"href": "https://ecat.kr/wp-json/wp/v2/posts/916/revisions"
}
],
"wp:attachment": [
{
"href": "https://ecat.kr/wp-json/wp/v2/media?parent=916"
}
],
"wp:term": [
{
"taxonomy": "category",
"embeddable": true,
"href": "https://ecat.kr/wp-json/wp/v2/categories?post=916"
},
{
"taxonomy": "post_tag",
"embeddable": true,
"href": "https://ecat.kr/wp-json/wp/v2/tags?post=916"
}
],
"wp:action-publish": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-unfiltered-html": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-sticky": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-assign-author": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-create-categories": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-assign-categories": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-create-tags": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"wp:action-assign-tags": [
{
"href": "https://ecat.kr/wp-json/wp/v2/posts/916"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}
위의 스크린샷에서 보시다시피 성공적으로 글 등록이 되었습니다. 👍👍
사용자 정의 값 함수 인자로 받기
테스트를 위해서 사용자들이 작성해야 할 값들을 코어 프로세스에 하드코딩으로 입력 해놓았는데 이런 값들을 추려서 메인 프로세스에서 설정 하도록 수정 해보자.
먼저 수정해야할 항목을 보면,
- URL
- 워드프레스 아이디, 비밀번호
- 글 제목
- 글 본문 내용
- 발행 상태 설정
이 부분들을 모두 변수 처리 한 후 “메인 프로세스” 에서 함수 인자 값으로 넘기는 것으로 대체 해보자.
# 워드프레스 자동 포스팅 함수
def createPost(userInfo, postInfo):
함수 인자 값으로 워드프레스 접속정보, 워드프레스 포스팅 정보 를 받도록 설정을 하였으며, 메인 프로세스에서도 각 항목에 맞게 변수 값을 지정해서 인자 값을 전달 하도록 수정 해보자.
글 제목이나 본문 내용등 각각 인자 값으로 설정을 해도 되지만 차후에 더 많은 정보를 입력하도록 수정 하고 싶을 때 함수명 쪽을 계속 건드려야 하는 번거로움이 생긴다.
이를 미연에 방지하고자 확장성 있게 postInfo = 글 모든 데이터 형식으로 지정 한 것이다.
이번에는 메인쪽 소스를 보자.
if __name__ == "__main__":
# 워드프레스 접속 정보
userInfo = {
'url': 'ecat.kr',
'username': '워드프레스 아이디',
'password': '워드프레스 비밀번호'
}
# 워드프레스 포스팅
postInfo = {
'title' : '글 제목 입니다.',
'contents' : '본문 내용 입니다.',
'category' : '여행',
'tag' : '',
'status' : 'draft'
}
createPost(userInfo, postInfo)
위와 같이 모든 사용자 정의 값은 외부로 빼냈으니 createPost() 함수 내부에 하드코딩 된 부분을 모두 변수 처리 해주자.
import requests, openai
from bs4 import BeautifulSoup
from time import sleep
# 워드프레스 자동 포스팅 함수
def createPost(userInfo, postInfo):
# 워드프레스 JWT 인증 토큰 얻기
url = f"https://{userInfo.get('url')}/wp-json/jwt-auth/v1/token"
data = {
'username': userInfo.get('username'),
'password':userInfo.get('password')
}
res = requests.post(url, data=data).json()
token = res.get('token')
# 헤더에 JWT 인증 토큰 데이터 추가
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {token}'
}
# 워드프레스 포스팅 데이터 설정
postURL = f"https://{userInfo.get('url')}/wp-json/wp/v2/posts"
postData = {
'title': postInfo.get('title'),
'slug': postInfo.get('title').replace(' ', '-'),
'content': postInfo.get('contents'),
'meta': {
'category': postInfo.get('category')
},
'status': postInfo.get('status')
}
# 워드프레스 포스팅 생성 요청 보내기
response = requests.post(postURL, json=postData, headers=headers)
"""
메인 프로세스
"""
if __name__ == "__main__":
# 워드프레스 접속 정보
userInfo = {
'url': 'ecat.kr',
'username': '워드프레스 아이디',
'password': '워드프레스 비밀번호'
}
# 워드프레스 포스팅
postInfo = {
'title' : '글 제목 입니다.',
'contents' : '본문 내용 입니다.',
'category' : '여행',
'tag' : '',
'status' : 'draft'
}
createPost(userInfo, postInfo)
위와 같이 모두 변수 수정 후 실행 해보면 큰 문제 없이 정상적으로 글 등록이 되는 것을 볼 수 있다.
이젠 글 작성 정보를 복잡한 함수 내부에서 수정할 필요 없이 메인 프로세스에서 변경 해주면 된다.
마치며
이번 포스팅 에서는 워드프레스 Rest API 를 이용하여 글 등록하는 기능을 구현 해보았다.
다음 포스팅에서는 ChatGPT 를 활용하는 법에 대해서 알아보도록 하겠다. 😎😎