Post using Wordpress REST API

Post using Wordpress REST API

Date
May 21, 2018
Tags
Programming
WordPress REST API 可以讓我們透過 JSON request 很方便的建立及發佈 post。這篇文章是分享一下實際的操作。首先大家可以到這裡參考一下 wordpress 官方的 document。
我會示範寫一個 Python 程序,然後透過調用 WordPress 的 Rest API,來發佈 Post。
如果你還未有一個 wordpress 的伺服器,建議你使用 bluehost 的 web hosting 服務,穩定快速又便宜。

設定你的 wordpress 伺服器

經過一些研究,發覺 WordPress 暫時只支援 Cookie 的認證方式。其它的認證方式都要安裝不同的 Plugin。因為我們會使用 Python 程序,亦是為了方便,我們這次只會使用 HTTP Basic Authentication,就是 ID 和密碼的方式得到 WordPress 的認證。如要做到這點,要在自己網站的 WordPress 安裝一個 JSON Basic Auth Manager ,可以在 WordPress 裡的 Admin 頁自動安裝。也可以到這個 Plugin 的 Github 裡下載自行安裝。
notion image
這個 plugin 打開來看的話是很簡單的。就把 Server variable 裡拿到的 user 和 id 用來認證。但有一點要注意,有時 Apache 伺服器會把 Authorization 的資料從 request header 中拿去。如發生這種情況,要到 server 裡的 .htaccess 修改。加入以下一句
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
這句意思是如果見到 header 有 Authorization 資料,就要設定 HTTP_AUTHORIATION 這個變量內,讓 plugin 可以讀到。
有一點要注意的是,如果你用的 Apache 伺服器是用 Bitnami 安裝的話 (例如 Google Compute Engine),這個安裝就預設是不會看 .htaccess 的。要改的話應要到你的 apps/[application]/conf/httpd-app.conf 才可以。

簡單用 curl 測試 Rest API 連結

當伺服器都設定妥當後,最簡單的測試方法是在 Terminal 裡輸入以下的 curl 指令,記得要把 [targetURL] 換成你的 wordpress 網址
curl -X GET [targetURL]/wp-json/wp/v2/posts"
如能看到 JSON response 的話,證明你的設定經已成功

在 Postman 裡測試

關於 Rest API 的開發,我們都會用 Postman。大家可以下載。
要建立一個新的 post,我們會在 Postman 裡輸入 ID 和 密碼的資料,然後也填上 contnt 和 title。用 postman 的好處是它會簡單地為你的密碼做 base64 encoding,也會在背後填上很多所需要的 header 資料。
填好後按 SEND。你會看到新建立的 Post 的資料。這時你登入到 wordpress 看的話,也應該可以見到這個新 Post。預設的情況下這個 Post 會是在 Draft 的狀態。
notion image
除了 content 和 title 這兩個必要的參數外,在 send post request 前也可以填上 status 及 categories。status 方面如想直接就發佈,可以填上 ‘publish’。而 categories 就是指你想把 post 放在那個 category 下。你可以到 WordPress 數據庫內找 wp_terms 這個表。因為我是用 wordpress multisite,所以我這個網站的表是 wp_3_terms。
select * from wp_3_terms;
notion image
如上圖,可以看到如果我想把 post 放在 ‘Quora 解答’ 這個 category 的話,我只需在 request 裡設定  categories = 28

編寫程序做到自動發佈

上面所有都測試好沒問題後,到最後其實就不很難了。我以下分享我的這個 function。不完整,因為你要自己填上你的密碼及要 post 的內容等。這裡最重要的是你的 ID 和密碼要用 base64 encoding 並放進 reqeust header 內,做法可以參考下面。
from urllib.request import urlopen from urllib.parse import quote, urlencode import urllib from bs4 import BeautifulSoup import base64 import json import configparser import sys config = configparser.ConfigParser() config.sections() config.read(sys.path[0] + '/pw.config') wpUrl = 'https://jackchan.hk/' encoding = 'utf-8' authString = '%s:%s' % (config['jackchan.hk']['user'], config['jackchan.hk']['pw']) authStringB64 = base64.b64encode(authString.encode('ASCII')) quora_image_code = 803 hdr = {'Authorization' : 'Basic %s' % authStringB64.decode('ASCII'), 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', 'Accept': 'text/html,application/xhtml+xml,application/json, application/xml;q=0.9,*/*;q=0.8', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Accept-Encoding': 'utf-8', 'Accept-Language': 'en-US,en;q=0.8', 'Connection': 'keep-alive'} def upload_to_WP(title, content): target_url = wpUrl + 'wp-json/wp/v2/posts' data = dict(content=content, title=title, categories=28, status='publish', featured_media = quora_image_code) data = bytes(urlencode(data).encode()) try: request = urllib.request.Request(url = target_url, data = data, headers= hdr) result = urlopen(request) messages = result.read() print(messages) except IOError as e: print(e)
最後提醒一下,如果你的網站和我一樣,是有用 SSL 加密的話,而你又是在 Mac 上運行 Python 3.6 的話,你可能會碰到 connection error。這個時候你要安裝 Certificate,運行以下的 command 就可以了。
/Applications/Python\ 3.6/Install\ Certificates.command