メインメニューを開く

MediaWikiAPIを利用してC♯でページを作成・編集する

2019年7月26日 (金) 16:34時点におけるRin-scrooge (トーク | 投稿記録)による版 (→‎どんなメッセージを送っているの?)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

C#を使ってMediaWikiにページを作成したり編集したりするよ。僕が使っているMediaWikiのバージョンは1.22.2だから、これベースに説明するよ。
じつは、ログインが必要ないWikiでこのプログラムを試したことがないんだ。だから、ログインしてからWikiを更新するソースを紹介するね。

大まかな流れ

MediaWikiにAPIからページを作成・編集するためには、ページ編集用のトークンが必要だよ。
ほとんどの場合、MediaWikiの設定でログインしないと編集できない様にしていると思うから、ログインしてから編集してね。
ページ編集用トークンは「action=tokens」を送信すると取得できるよ。
つまり…

「editトークンを取得 → ページを作成・編集」

って流れになるよ。
ログインするC♯のロジックは「MediaWikiAPIを利用してC♯でログインする」に載ってるよ。

ソース

このWikiにページを作成・編集することを想定してソースを作成したよ。 このソースは最後にページの作成・編集ができているか確認していないけど、みんなはちゃんと確認してね。サーバーからの応答はXMLで返却されるから分析してね。

//参照を追加してね
using System.Xml;
using System.Net;
using System.IO;
using System.Web; //←こいつはアセンブリの追加が必要だよ

namespace WikiEditLib
{
    public class WikiEdit
    {
        /// <summary>
        /// ログインしてる場合のページの作成・編集だよ
        /// </summary>
        /// <param name="p_CookieContainer">ログインの時に使ったクッキーを渡してね</param>
        public void LoginEdit(CookieContainer p_CookieContainer)
        {
            //文字列を送信するために必要なインスタンスをあらかじめ生成しておくよ
            //「http://rindomain.com/rinwiki/api.php」は自分のWikiの環境に合わせて書き直してね
            Uri l_Uri = new Uri("http://rindomain.com/rinwiki/api.php");
            
            //editトークンを取得するための文字列を生成するよ
            StringBuilder l_StringBuilder = new StringBuilder();
            l_StringBuilder.Append("action=tokens");
            l_StringBuilder.Append("&type=edit");
            l_StringBuilder.Append("&format=xml");

            //バイト配列に変換するよ
            Byte[] l_ByteArray = UTF8Encoding.UTF8.GetBytes(l_StringBuilder.ToString());

            //WebRequestのインスタンスを生成するよ
            HttpWebRequest l_HttpWebRequest = (HttpWebRequest)WebRequest.Create(l_Uri);
            l_HttpWebRequest.Method = "POST";
            l_HttpWebRequest.ContentType = "application/x-www-form-urlencoded";
            l_HttpWebRequest.CookieContainer = p_CookieContainer;

            //editトークンを取得するための文字列を送信するよ
            Stream l_Stream = l_HttpWebRequest.GetRequestStream();
            l_Stream.Write(l_ByteArray, 0, l_ByteArray.Length);
            l_Stream.Close();

            //サーバーからの応答を受信するよ
            WebResponse l_WebResponse = l_HttpWebRequest.GetResponse();
            StreamReader l_StreamReader = new StreamReader(l_WebResponse.GetResponseStream());
            String l_ResponseString = l_StreamReader.ReadToEnd();
            l_StreamReader.Close();
            l_WebResponse.Close();

            //editトークンを取得するよ
            String l_EditToken = String.Empty;
            XmlDocument l_XmlDocument = new XmlDocument();
            l_XmlDocument.LoadXml(l_ResponseString);
            foreach (XmlElement f_XmlElement in l_XmlDocument.DocumentElement)
            {
                l_EditToken = f_XmlElement.GetAttribute("edittoken");
                if (l_EditToken != String.Empty)
                {
                    break;
                }
            }

            //ページの作成・更新するための文字列を生成するよ
            l_StringBuilder.Clear();
            l_StringBuilder.Append("action=edit");
            l_StringBuilder.Append("&title=");
            l_StringBuilder.Append(HttpUtility.UrlEncode("タイトル"));
            l_StringBuilder.Append("&text=");
            l_StringBuilder.Append(HttpUtility.UrlEncode("= 見出し =\r\n本文"));
            l_StringBuilder.Append("&token=");
            l_StringBuilder.Append(HttpUtility.UrlEncode(l_EditToken));
            l_StringBuilder.Append("&format=xml");

            //バイト配列に変換するよ
            l_ByteArray = UTF8Encoding.UTF8.GetBytes(l_StringBuilder.ToString());

            //WebRequestのインスタンスを生成するよ
            l_HttpWebRequest = (HttpWebRequest)WebRequest.Create(l_Uri);
            l_HttpWebRequest.Method = "POST";
            l_HttpWebRequest.ContentType = "application/x-www-form-urlencoded";
            l_HttpWebRequest.CookieContainer = p_CookieContainer;

            //ページを作成・編集するための文字列を送信するよ
            l_Stream = l_HttpWebRequest.GetRequestStream();
            l_Stream.Write(l_ByteArray, 0, l_ByteArray.Length);
            l_Stream.Close();

            //サーバーからの応答を受信するよ
            l_WebResponse = l_HttpWebRequest.GetResponse();
            l_StreamReader = new StreamReader(l_WebResponse.GetResponseStream());
            l_ResponseString = l_StreamReader.ReadToEnd();
            l_StreamReader.Close();
            l_WebResponse.Close();
        }
    }
}

どんなメッセージを送っているの?

editトークンの取得
http://rindomain.com/rinwiki/api.php ? action=tokens & type=edit & format=xml
ページの作成・更新
http://rindomain.com/rinwiki/api.php ? action=edit & title=[タイトル] & text=[本文] & token=[取得したトークン] & format=xml