Skip to content

[WordPress] 使用 REST API 發表文章

最近比較多網友詢問了我關於如何透過程式在 WordPress 上發表文章,正好藉這次的機會,嘗試使用之前比較沒有研究的 REST API 來達到發表文章的目的。


什麼是 REST API

REST(Representational State Transfer, 表現層狀態轉換)是一種架構相對簡潔的網路傳遞資訊建構風格。使用者只需要根據自己的需求設定好 HTTP 的參數、屬性,便可以在伺服器的接口上,使用不同的軟體及程式發出請求。

所以,REST 本身是一種設計的『風格』。而今天我要紀錄的,則是所謂的 WordPress REST API,也即是 WordPress 面向開發人員所設計程式接口。

如果我的解釋有未盡之處,請參閱官方的手冊:https://developer.wordpress.org/rest-api/

而我們要若要使用 WordPress REST API,則需要完成下面兩個步驟:

  • 建立『Application Passwords』
  • 撰寫程式執行操作

其實並不複雜。


Application Passwords

在 WordPress 5.6 及以後版本中,這個功能已經預設開啟;而若低於此版本的話,則建議可以搜尋相關的外掛,比方說著名的『Application Passwords』plugin 來啟用。

首先前往後台,在左側選單中找到 “User“-> “Profile“。


往下找到 Application Passwords 的欄位,並設定新的應用程式名稱。這裡可以取個有意義、不會忘記的名稱,幫助自己辨識。


建立完畢後,應該會看到隨機產生的密碼。密碼應是英數混雜、大小寫區分的以下格式:

xxxx xxxx xxxx xxxx xxxx xxxx


最後別忘了更新 profile。我第一次操作時忘記更新,導致我後續步驟一直失敗,十分悲憤。


撰寫程式執行操作

在這一小節,我使用 Python 程式語言來發出請求。如有其他熟悉的語言,也可以使用其他語言進行請求,並無限制。

我會紀錄以下幾個 demo:

  • 確認 REST API 能夠訪問網站
  • 發表文章
  • 更新文章
  • 刪除文章


確認 REST API 能夠訪問網站

首先,這是最重要的一步。若是訪問時返回的網頁狀態碼並非 200,則需要上網查詢相關資訊,並依照錯誤訊息進行調整。

# coding: utf-8
import base64
import json
import requests
from pprint import pprint


def main():
    # Init
    url = "https://YOURS.com/wp-json/wp/v2/posts"
    username = "USERNAME"
    password = "PASSWORD"
    credentials = "{}:{}".format(username, password)
    token = base64.b64encode(credentials.encode())

    # Header
    headers = {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
        "Authorization": "Basic {}".format(token.decode("utf-8")),
        "content-type": "application/json",
    }

    # Check
    r = requests.get(
        url,
        headers=headers,
    )
    
    # Print
    print(r)


if __name__ == "__main__":
    main()


Output:

<Response [200]>


這裡介紹幾個重要的參數:

  • url: 你的 WordPress 網站中 REST API 位址
  • username:帳號,也可能是你的電子郵件地址
  • password:這裡並不是真的密碼,而是剛剛所生成的『應用程式密碼
  • headers:標頭。這裡的 3 個參數都很重要。

若程式回傳了狀態碼 200,那麼恭喜!你的 WordPress 網站使用 REST API 多半是沒有問題的。


發表文章

發表文章跟剛才的操作很像,只是從 get() 變成了 post()

與此同時,還需要額外設定文章的資訊。詳細情況請參閱下方程式碼:

# coding: utf-8
import base64
import json
import requests
from pprint import pprint


def main():
    # Init
    url = "https://YOURS.com/wp-json/wp/v2/posts"
    username = "USERNAME"
    password = "PASSWORD"
    credentials = "{}:{}".format(username, password)
    token = base64.b64encode(credentials.encode())

    # Header
    headers = {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
        "Authorization": "Basic {}".format(token.decode("utf-8")),
        "content-type": "application/json",
    }

    # Post info
    post = {
        "title": "This is a REST API test",
        "content": "Accessed.",
        "status": "draft",
    }

    # Post
    r = requests.post(
        url,
        headers=headers,
        json=post,
    )
    
    # Print
    pprint(r.text)


if __name__ == "__main__":
    main()


Output:

('{"id":5204,"date":"2021-03-22T04:58:33","date_gmt":"2021-03-22T04:58:33","guid":{"rendered":"https:\\/\\/clay-atlas.com\\/?p=5204","raw":"https:\\/\\/clay-atlas.com\\/?p=5204"},"modified":"2021-03-22T04:58:33","modified_gmt":"2021-03-22T04:58:33","password":"","slug":"","status":"draft","type":"post","link":"https:\\/\\/clay-atlas.com\\/?p=5204","title":{"raw":"This '
 'is a REST API test","rendered":"This is a REST API '
 'test"},"content":{"raw":"Accessed.","rendered":"<p>Accessed.<\\/p>\\n","protected":false,"block_version":0},"excerpt":{"raw":"","rendered":"<p>Accessed.<\\/p> ...


若返回了上方資訊,則代表發表成功(雖然只是草稿)。你應該可以在後台看到我們剛才新增的草稿:

內容也與剛才設定的並無二致。


更新文章

還記得剛才發表文章後,我們螢幕上所印出的文章 ID: 5204 嗎?當然,當你測試的時候,你的文章 ID 會與我的不同;若要更新該篇文章的話,則需要記起文章的 ID。

可以參考下方程式碼:

# coding: utf-8
import base64
import json
import requests
from pprint import pprint


def main():
    # Init
    url = "https://YOURS.com/wp-json/wp/v2/posts"
    username = "USERNAME"
    password = "PASSWORD"
    credentials = "{}:{}".format(username, password)
    token = base64.b64encode(credentials.encode())

    # Header
    headers = {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
        "Authorization": "Basic {}".format(token.decode("utf-8")),
        "content-type": "application/json",
    }

    # Post info
    post_id = 5204 # <--- add post id
    post = {
        "title": "This is a REST API test",
        "content": "Updated!", # <--- change the content
        "status": "draft",
    }

    # Post
    r = requests.post(
        "{}/{}".format(url, post_id), # <--- change the url
        headers=headers,
        json=post,
    )
    
    # Print
    pprint(r.text)


if __name__ == "__main__":
    main()


Output:

執行程式後,再次打開文章,應該會發現文章內容已經被更新了。


刪除文章

刪除文章就只需要文章的 ID、以及將 post() 修改為 delete() 即可。

# coding: utf-8
import base64
import json
import requests
from pprint import pprint


def main():
    # Init
    url = "https://YOURS.com/wp-json/wp/v2/posts"
    username = "USERNAME"
    password = "PASSWORD"
    credentials = "{}:{}".format(username, password)
    token = base64.b64encode(credentials.encode())

    # Header
    headers = {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
        "Authorization": "Basic {}".format(token.decode("utf-8")),
        "content-type": "application/json",
    }

    # Post info
    post_id = 5204

    # Delete
    r = requests.delete( # <--- change "post" to "delete"
        "{}/{}".format(url, post_id),
        headers=headers,
    )
    
    # Print
    pprint(r.text)


if __name__ == "__main__":
    main()


Output:

這時我們再去後台查看,應該會發現此篇文章已經被收至垃圾桶中了。


References


Read More

5 thoughts on “[WordPress] 使用 REST API 發表文章”

  1. 我在你更新的時候,就嘗試的去用REST API更新文章,但大多得到都是400、401、403的錯誤,剛好你今天也更新文章,我有使用你的程式碼,第一段程式碼回傳200,那表示網站使用 REST API 多半是沒有問題的,但只要使用post之後,就開始回傳錯誤碼,這次是回傳401,讓我不禁思考是不是我的網站哪個地方設定錯誤

    1. 或許可以嘗試看看如何排除 401 的報錯:https://www.wpbeginner.com/wp-tutorials/how-to-fix-the-401-error-in-wordpress-solutions/
      當然你可能早已嘗試過了也說不定,牽涉到更改後台安全防護時仍須小心。
      希望你能早日成功,加油!

    2. 請容我再次追加我的回覆。
      網頁狀態碼 401 是跟授權有關,建議檢查帳號與應用程式密碼是否輸入正確。
      另外也可以考慮暫時關閉安全防護性的插件並再次執行程式碼。
      祝一切順利。

  2. 在此感謝你的用心回覆,真的給予我很大的幫助,在聽了你的建議之後,我嘗試將所有的外掛關閉,並且再次去個人資料重新換一個新密碼(這動作之前也是一直重複做),結果就順利的將程式執行成功!!!後續我將所有外掛又重新開啟,依然可以執行,在這過程我只做了關閉外掛,重新換一個密碼。這裡也感謝你提供除了發文以外的其他程式碼,真的非常有幫助,我會在嘗試更多的功能。感謝你,你的網站提供很好的價值

Leave a Reply