今回はWordPress RestAPIを使って全投稿データをCSVに書き出すようにしてみます
動作環境は以下です
バージョン | |
---|---|
OS | WIn 11 Pro |
C# | .Net 8.0 |
WordPress | 6.5.2 |
アプリケーションパスワードを準備する
今回はアプリケーションパスワード認証でRestAPIを使用するため、以下のサイトが参考になります。以下のサイトはGAS(Google Apps Script)での実装する際に必要となる手順(サーバーのREST APIのアクセス制限を無効にする方法)がありますが今回は必要ありません。国内からのアクセスを想定しているためです
-
WordPress REST APIを有効化する方法※2022年版│Programming ZERO
本記事ではWordPressの自動記事投稿や記事情報の自動取得を可能にする「WordPress REST API」を利用 ...
続きを読む
Getメソッド関数を実装する
対象URLに対してGetする箇所を関数かしておきます
private string _apiKey = @"前の項目で取得したアプリケーションパスワード(文字列の間にある空欄ありのままで)";
private string _userName = "前の項目でアプリケーションパスワードを設定したユーザー名";
private string _hostName = "WordPressのサイトURL"; // 本サイトの場合は「https://nasuton.net/blog」となる
/// <summary>
/// 対象URLに対してGetリクエストを送信する
/// </summary>
/// <param name="url">GETメソッドのURL</param>
/// <returns>レスポンス結果</returns>
private async Task<HttpResponseMessage> GetAPIAsync(string url)
{
HttpResponseMessage response;
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), url))
{
// Basic 認証のヘッダを追加
var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_userName}:{_apiKey}"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
response = await httpClient.SendAsync(request);
}
}
return response;
}
タグ情報を取得する
まずはタグ情報を取得します。今回はId、タグのURL、タグの表示名を取得するようにしています。
また、初期値では1回のリクエストで10個ずつしか取得できないので、全部取得できるように繰り返しリクエストを投げています
/// <summary>
/// WordPressのタグ情報を格納するクラス
/// </summary>
public class WPTag_Response
{
public WPTag_Response() { }
[JsonPropertyName("id")]
public int? Id { get; set; }
[JsonPropertyName("link")]
public string? Link { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
}
/// <summary>
/// 全てのタグを取得する
/// </summary>
/// <returns>取得した全てのタグ情報</returns>
public List<WPTag_Response> GetAllTags()
{
var allTags = new List<WPTag_Response>();
var url = $"{_hostName}/wp-json/wp/v2/tags";
var response = GetAPIAsync(url).Result;
// Headerから総ページ数を取得
var wp_totalPages = int.Parse(response.Headers.GetValues("X-WP-TotalPages").First());
allTags.AddRange(JsonSerializer.Deserialize<List<WPTag_Response>>(response.Content.ReadAsStringAsync().Result));
// 2ページ目以降のデータを取得
if(wp_totalPages > 1)
{
for (int i = 2; i < wp_totalPages + 1; i++)
{
url = $"{_hostName}/wp-json/wp/v2/tags" + $"?page={i}";
response = GetAPIAsync(url).Result;
allTags.AddRange(JsonSerializer.Deserialize<List<WPTag_Response>>(response.Content.ReadAsStringAsync().Result));
}
}
return allTags;
}
カテゴリ情報を取得する
続いて、カテゴリ情報を取得します。こちらはId、カテゴリのURL、カテゴリの表示名を取得するようにしています。
こちらも先ほどのタグ同様に1回のリクエストで10個ずつしか取得できないので、全部取得できるように繰り返しリクエストを投げています
/// <summary>
/// WordPressのカテゴリ情報を格納するクラス
/// </summary>
public class WPCategory_Response
{
public WPCategory_Response() { }
[JsonPropertyName("id")]
public int? Id { get; set; }
[JsonPropertyName("link")]
public string? Link { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
}
/// <summary>
/// 全てのカテゴリを取得する
/// </summary>
/// <returns>取得したすべてのカテゴリ情報</returns>
public List<WPCategory_Response> GetAllCategories()
{
var allCategories = new List<WPCategory_Response>();
var url = $"{_hostName}/wp-json/wp/v2/categories";
var response = GetAPIAsync(url).Result;
// Headerから総ページ数を取得
var wp_totalPages = int.Parse(response.Headers.GetValues("X-WP-TotalPages").First());
allCategories.AddRange(JsonSerializer.Deserialize<List<WPCategory_Response>>(response.Content.ReadAsStringAsync().Result));
if (wp_totalPages > 1)
{
// 2ページ目以降のデータを取得
for (int i = 2; i < wp_totalPages + 1; i++)
{
url = $"{_hostName}/wp-json/wp/v2/categories" + $"?page={i}";
response = GetAPIAsync(url).Result;
allCategories.AddRange(JsonSerializer.Deserialize<List<WPCategory_Response>>(response.Content.ReadAsStringAsync().Result));
}
}
return allCategories;
}
投稿情報を取得する
今回は投稿情報(固定ページは含まない)だけを取得しています。こちらはId、投稿日時(公開日時?)、投稿の表示名、投稿のURL、カテゴリのId、タグのIdを取得するようにしています。
/// <summary>
/// WordPressの投稿データを格納するクラス
/// </summary>
public class WPPOST_Response
{
public WPPOST_Response() { }
[JsonPropertyName("id")]
public int? Id { get; set; }
[JsonPropertyName("date")]
public string? Date { get; set; }
[JsonPropertyName("title")]
public WP_TitleRendered? rendered { get; set; }
[JsonPropertyName("link")]
public string? Link { get; set; }
[JsonPropertyName("categories")]
public List<int>? Categories { get; set; }
[JsonPropertyName("tags")]
public List<int>? Tags { get; set; }
}
/// <summary>
/// WordPressのタイトルを格納するクラス
/// </summary>
public class WP_TitleRendered
{
public WP_TitleRendered() { }
[JsonPropertyName("rendered")]
public string? Title { get; set; }
}
/// <summary>
/// 全ての投稿を取得する
/// </summary>
/// <returns>取得した投稿データリスト</returns>
public List<WP_PostData> GetAllPosts()
{
var postDatas = new List<WP_PostData>();
var allPosts = new List<WPPOST_Response>();
var allTags = GetAllTags();
var allCategories = GetAllCategories();
var url = $"{_hostName}/wp-json/wp/v2/posts";
var response = GetAPIAsync(url).Result;
// Headerから総ページ数を取得
var wp_totalPages = int.Parse(response.Headers.GetValues("X-WP-TotalPages").First());
allPosts.AddRange(JsonSerializer.Deserialize<List<WPPOST_Response>>(response.Content.ReadAsStringAsync().Result));
if(wp_totalPages > 1)
{
// 2ページ目以降のデータを取得
for (int i = 2; i < wp_totalPages + 1; i++)
{
url = $"{_hostName}/wp-json/wp/v2/posts" + $"?page={i}";
response = GetAPIAsync(url).Result;
allPosts.AddRange(JsonSerializer.Deserialize<List<WPPOST_Response>>(response.Content.ReadAsStringAsync().Result));
}
}
foreach (var post in allPosts)
{
var postData = new WP_PostData
{
Id = post.Id,
Date = DateTime.Parse(post.Date).ToString("yyyy/MM/dd HH:mm:ss"),
Title = WebUtility.HtmlDecode(post.rendered.Title), // HTMLエンコードされた文字列をデコード
Link = post.Link,
Categories = new List<string>(),
Tags = new List<string>()
};
foreach (var categoryId in post.Categories)
{
var category = allCategories.Find(c => c.Id == categoryId);
postData.Categories.Add(category.Name);
}
foreach (var tagId in post.Tags)
{
var tag = allTags.Find(t => t.Id == tagId);
postData.Tags.Add(tag.Name);
}
postDatas.Add(postData);
}
return postDatas;
}
取得したデータの一部はそのままでは使えないのでタグとカテゴリをIdではなく表示名にし、投稿タイトルもHTMLエンコードしている可能性があるのでそれをデコードしています
CSVファイルに書き出す
これまでに取得したデータをCSVファイルとして実際に書き出します。タグとカテゴリは複数ある場合があるのでそれを「|」で区切っています
/// <summary>
/// CSVファイルにWordPressの投稿データを書き込む
/// </summary>
/// <param name="postDatas">投稿データリスト</param>
public void WP_PostDataCSV_Write(List<WP_PostData> postDatas)
{
string csvPath = AppSetting.GetString("csvPath");
using (var writer = new StreamWriter(csvPath, false, Encoding.UTF8))
{
// ヘッダーを書き出し
writer.WriteLine("Id,Date,Title,Link,Categories,Tags");
// データを書き出し
foreach (var post in postDatas)
{
writer.WriteLine($"{post.Id},{post.Date},{post.Title},{post.Link},{string.Join("|", post.Categories)},{string.Join("|", post.Tags)}");
}
}
}
最後に
今回は投稿データとカテゴリ、タグの情報を取得するだけでしたがほかにも色々とできるようなので以下のドキュメント(英語で書かれています)を参考に実装してみてください
-
REST API Handbook | Developer.WordPress.org
The WordPress REST API provides an interface for application ...
続きを読む
また、今回作成したコードもGitHubにアップしていますので参考にしてみてください
-
BlogSampleCodeProjects/WPRestAPI at main · nasuton/BlogSampleCodeProjects · GitHub
Project for sample code used in the blog.(Blogで記載しているサンプルコード ...
続きを読む
会社紹介
私が所属しているアドバンスド・ソリューション株式会社(以下、ADS)は一緒に働く仲間を募集しています
会社概要
「技術」×「知恵」=顧客課題の解決・新しい価値の創造
この方程式の実現はADSが大切にしている考えで、技術を磨き続けるgeekさと、顧客を思うloveがあってこそ実現できる世界観だと思っています
この『love & geek』の精神さえあれば、得意不得意はno problem!
技術はピカイチだけど顧客折衝はちょっと苦手。OKです。技術はまだ未熟だけど顧客と知恵を出し合って要件定義するのは大好き。OKです
凸凹な社員の集まり、色んなカラーや柄の個性が集まっているからこそ、常に新しいソリューションが生まれています
ミッション
私たちは、テクノロジーを活用し、業務や事業の生産性向上と企業進化を支援します
-
アドバンスド・ソリューション株式会社
アドバンスド・ソリューションは主にMicrosoft製品を使用して、企業の生産性向上に取り組んでいます。要件定義から導入 ...
サイトへ移動
-
お問い合わせ | アドバンスド・ソリューション株式会社
お問い合わせはこちら