{"id":805,"date":"2020-07-07T00:09:10","date_gmt":"2020-07-06T15:09:10","guid":{"rendered":"https:\/\/www.typea.info\/blog\/?p=805"},"modified":"2020-07-07T00:09:10","modified_gmt":"2020-07-06T15:09:10","slug":"mediawiki-delete-spam-page-and-invalid-users","status":"publish","type":"post","link":"https:\/\/www.typea.info\/blog\/index.php\/2020\/07\/07\/mediawiki-delete-spam-page-and-invalid-users\/","title":{"rendered":"Mediawiki \u306e\u30b9\u30d1\u30e0\u30da\u30fc\u30b8\u3068\u4e0d\u6b63\u30e6\u30fc\u30b6\u30fc\u3092\u4e00\u62ec\u3067\u524a\u9664\u3059\u308b\u306a\u3069"},"content":{"rendered":"<p><a href=\"https:\/\/www.amazon.co.jp\/MediaWiki%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%97%E3%82%AC%E3%82%A4%E3%83%89%E2%80%95%E3%81%82%E3%81%AA%E3%81%9F%E3%82%82Wikipedia%E3%81%8C%E4%BD%9C%E3%82%8C%E3%82%8B-%E9%8E%8C%E6%BB%9D-%E9%9B%85%E4%B9%85\/dp\/4883375536\/ref=as_li_ss_il?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;dchild=1&amp;keywords=mediawiki&amp;qid=1594047932&amp;sr=8-1&amp;linkCode=li2&amp;tag=typea09-22&amp;linkId=b18d5b3dfc1cff0f31fb13bf0d1cf100&amp;language=ja_JP\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"\/\/ws-fe.amazon-adsystem.com\/widgets\/q?_encoding=UTF8&amp;ASIN=4883375536&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=JP&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=typea09-22&amp;language=ja_JP\" border=\"0\"><\/a><img loading=\"lazy\" decoding=\"async\" width=\"1\" height=\"1\" style=\"margin: 0px !important; border: currentcolor !important; border-image: none !important;\" alt=\"\" src=\"https:\/\/ir-jp.amazon-adsystem.com\/e\/ir?t=typea09-22&amp;language=ja_JP&amp;l=li2&amp;o=9&amp;a=4883375536\" border=\"0\"><\/p>\n<p>Mediawiki\u306b\u4e0d\u6b63\u30a2\u30af\u30bb\u30b9\u3055\u308c\u3066\u5bfe\u51e6\u3057\u305f\u306e\u3060\u304c\u3001\u306a\u304b\u306a\u304b\u9762\u5012\u3060\u3063\u305f\u306e\u3067\u3001\u4eca\u5f8c\u306e\u305f\u3081\u306b\u30e1\u30e2\u3002<\/p>\n<p><\/p>\n<h2>1.Mediawiki \u306b\u4f55\u5343\u4eba\u3082\u306e\u4e0d\u6b63\u30e6\u30fc\u30b6\u30fc\u304c\u4f5c\u6210\u3055\u308c\u305f\u3002\u3002\u3002<\/h2>\n<p><a href=\"http:\/\/typea.info\/tips\">FreeStyleWiki<\/a> \u304b\u3089 <a href=\"https:\/\/typea.info\/tips_\">Mediawiki<\/a>\u306b \u79fb\u884c\u4f5c\u696d\u3092\u3057\u3066\u3044\u308b\u3002\u81ea\u5206\u304c\u3069\u3053\u304b\u3089\u3067\u3082\u30e1\u30e2\u3092\u8ffd\u52a0\u3067\u304d\u308b\u3088\u3046\u306b\u305f\u3066\u3066\u3044\u308bWiki\u306a\u306e\u3067\u3001<\/p>\n<p><a href=\"https:\/\/www.mediawiki.org\/wiki\/Manual_talk:$wgGroupPermissions\">\u3053\u306e\u3042\u305f\u308a\u306e\u30da\u30fc\u30b8<\/a>\u306b\u3042\u308b\u3088\u3046\u306b sysop \u306b\u306e\u307f edit\u6a29\u9650\u3092\u4e0e\u3048\u308b\u3064\u3082\u308a\u3060\u3063\u305f\u3068\u601d\u3046\u306e\u3060\u304c\u3001<\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/07\/mediawiki_install.png\"><img loading=\"lazy\" decoding=\"async\" width=\"608\" height=\"195\" title=\"mediawiki_install\" style=\"display: inline; background-image: none;\" alt=\"mediawiki_install\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/07\/mediawiki_install_thumb.png\" border=\"0\"><\/a><\/p>\n<p>Mediawiki\u306e\u52dd\u624b\u304c\u308f\u304b\u3089\u306a\u304b\u3063\u305f\u306e\u304b\u3001\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u3068\u306a\u3063\u3066\u3044\u305f\u3002<\/p>\n<p>$wgGroupPermissions[&#8216;*&#8217;][&#8216;edit&#8217;] = false;<\/p>\n<p>$wgGroupPermissions[&#8216;<font color=\"#ff0000\">user<\/font>&#8216;][&#8216;edit&#8217;] = true;<\/p>\n<p><\/p>\n<p>\u3053\u306e\u305f\u3081\u3001\u30e6\u30fc\u30b6\u30fc\u306e\u4f5c\u6210\u306f\u81ea\u7531 \u2192 \u30e6\u30fc\u30b6\u30fc\u3067\u30ed\u30b0\u30a4\u30f3\u3059\u308c\u3070\u7de8\u96c6\u3057\u653e\u984c\u306a\u72b6\u614b\u306b\u306a\u3063\u3066\u304a\u308a\u3001<\/p>\n<p>\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u8f9e\u66f8\u3067\u7d44\u307f\u5408\u308f\u305b\u3092\u4f5c\u6210\u3057\u305f\u3088\u3046\u306a\u30e6\u30fc\u30b6\u30fc\u304c1\u4e07\u4ef6\u307b\u3069\u4f5c\u6210\u3055\u308c\u3066\u3057\u307e\u3063\u3066\u3044\u305f\u3002<\/p>\n<p>\u3067\u3001\u4e0d\u6b63\u30e6\u30fc\u30b6\u30fc\u3067\u30ed\u30b0\u30a4\u30f3\u3055\u308c\u3066\u3001\u30b9\u30d1\u30e0\u306a\u30da\u30fc\u30b8\u304c\u3053\u308c\u307e\u305f\u5927\u91cf\u306b\u4f5c\u6210\u3055\u308c\u3066\u3057\u307e\u3063\u3066\u3044\u305f\u3002<\/p>\n<p><\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/07\/mediawiki_spam_users.png\"><img loading=\"lazy\" decoding=\"async\" width=\"406\" height=\"372\" title=\"mediawiki_spam_users\" style=\"display: inline; background-image: none;\" alt=\"mediawiki_spam_users\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/07\/mediawiki_spam_users_thumb.png\" border=\"0\"><\/a><\/p>\n<h2>2.\u5bfe\u51e6\u3059\u308b\u3002<\/h2>\n<p>\u304f\u305d\u3080\u304b\u3064\u304f\u304c\u3001\u81ea\u3089\u306e\u624b\u843d\u3061\u306a\u306e\u3067\u3042\u304d\u3089\u3081\u3066\u3001\u4ee5\u4e0b\u306e\u5bfe\u5fdc\u3092\u9806\u6b21\u3068\u308b\u3002<\/p>\n<ol>\n<li>LocalSettings\u3067\u6a29\u9650\u3092\u53b3\u683c\u306b\u3010\u7dca\u6025\u3011<\/li>\n<li>MySQL\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3010\u7dca\u6025\u3011<\/li>\n<li>API\u3092\u7528\u3044\u3066\u30b9\u30d1\u30e0\u30da\u30fc\u30b8\u524a\u9664\u3010\u307c\u3061\u307c\u3061\u3011<\/li>\n<li>\u4e0d\u6b63\u30e6\u30fc\u30b6\u30fc\u306e\u524a\u9664\u3010\u307c\u3061\u307c\u3061\u3011<\/li>\n<\/ol>\n<p><\/p>\n<h3>2.1&nbsp; LocalSettings \u3067\u6a29\u9650\u3092\u53b3\u683c\u306b<\/h3>\n<p>\u4ee5\u4e0b\u306eURL\u3092\u53c2\u8003\u306b\u3001<\/p>\n<p><a href=\"https:\/\/www.mediawiki.org\/wiki\/Manual:User_rights\/ja\">https:\/\/www.mediawiki.org\/wiki\/Manual:User_rights\/ja<\/a><\/p>\n<p>\u307e\u305f\u3001<a href=\"https:\/\/www.typea.info\/tips_\/index.php\/%E7%89%B9%E5%88%A5:ListGrants\">\u6a29\u9650\u7fa4<\/a>\u3068\u3001<a href=\"https:\/\/www.typea.info\/tips_\/index.php\/%E7%89%B9%E5%88%A5:%E5%88%A9%E7%94%A8%E8%80%85%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E6%A8%A9%E9%99%90\">\u5229\u7528\u8005\u30b0\u30eb\u30fc\u30d7\u6a29\u9650\u4e00\u89a7<\/a>\u3092\u78ba\u8a8d\u3057\u306a\u304c\u3089\u3001\u30b0\u30ebLocalSettings.php\u3092\u7de8\u96c6\u3057\u3001\u30b0\u30eb\u30fc\u30d7\u6a29\u9650\u3092\u306f\u304c\u3057\u3066\u3044\u304f\u3002<\/p>\n<p><\/p>\n<p><pre class=\"prettyprint\">$wgGroupPermissions['sysop']['edit'] = true;\n$wgGroupPermissions['sysop']['writeapi'] = true;\n\n$wgGroupPermissions['*']['createpage'] = false;\n$wgGroupPermissions['*']['edit'] = false;\n$wgGroupPermissions['*']['createaccount'] = false;\n$wgGroupPermissions['*']['writeapi'] = false;\n$wgGroupPermissions['*']['editmywatchlist'] = false;\n$wgGroupPermissions['*']['editmyoptions'] = false;\n$wgGroupPermissions['*']['createtalk'] = false;\n$wgGroupPermissions['*']['editmyprivateinfo'] = false;\n$wgGroupPermissions['*']['viewmyprivateinfo'] = false;\n\n$wgGroupPermissions['user']['edit'] = false;\n$wgGroupPermissions['user']['move-categorypages'] = false;\n$wgGroupPermissions['user']['purge'] = false;\n$wgGroupPermissions['user']['upload'] = false;\n$wgGroupPermissions['user']['movefile'] = false;\n$wgGroupPermissions['user']['createpage'] = false;\n$wgGroupPermissions['user']['editcontentmodel'] = false;\n$wgGroupPermissions['user']['move'] = false;\n$wgGroupPermissions['user']['move-subpages'] = false;\n$wgGroupPermissions['user']['sendemail'] = false;\n$wgGroupPermissions['user']['changetags'] = false;\n$wgGroupPermissions['user']['reupload-shared'] = false;\n$wgGroupPermissions['user']['move-rootuserpages'] = false;\n$wgGroupPermissions['user']['reupload'] = false;\n$wgGroupPermissions['user']['writeapi'] = false;\n$wgGroupPermissions['user']['minoredit'] = false;\n$wgGroupPermissions['user']['editmyusercss'] = false;\n$wgGroupPermissions['user']['editmyuserjson'] = false;\n$wgGroupPermissions['user']['editmyuserjs'] = false;\n$wgGroupPermissions['user']['editmyuserjsredirect'] = false;\n$wgGroupPermissions['user']['applychangetags'] = false;\n$wgGroupPermissions['user']['createtalk'] = false;<\/pre>\n<p><\/p>\n<h3>2.2 MySQL\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7<\/h3>\n<p>\u6700\u60aa\u5fa9\u5143\u3067\u304d\u308b\u3088\u3046\u306b\u3001MySQL\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u53d6\u3063\u3066\u304a\u304f\u3002<\/p>\n<pre class=\"prettyprint\"># mysqldump --default-character-set=utf8 -uroot -p --all-databases &gt; mysqlbackup\n# tar -cvzf mysqlbackup.gz mysqlbackup<\/pre>\n<pre class=\"prettyprint\"><br><\/pre>\n<h3>2.3 \u30b9\u30d1\u30e0\u30da\u30fc\u30b8\u524a\u9664\u3068\u4e0d\u6b63\u30e6\u30fc\u30b6\u30fc\u306e\u524a\u9664<\/h3>\n<p>\u30da\u30fc\u30b8\u306e\u524a\u9664\u306f\u3001Mediawiki \u306e API\u3092\u547c\u3073\u51fa\u305b\u3070\u3088\u3044\u306e\u3060\u304c\u3001\u3069\u3046\u3084\u3089\u3001Mediawiki\u3067\u306f\u3044\u3063\u305f\u3093\u4f5c\u6210\u3055\u308c\u305f\u30e6\u30fc\u30b6\u30fc\u306f\u524a\u9664\u3067\u304d\u306a\u3044\u3088\u3046\u3060\u3002<\/p>\n<p>\u306a\u306e\u3067\u3001<a href=\"https:\/\/www.mediawiki.org\/wiki\/Extension:UserMerge\/ja\">Extension<\/a>\u3092\u5c0e\u5165\u3057\u3066\u3001\u524a\u9664\u3057\u305f\u3044\u30e6\u30fc\u30b6\u30fc\u3092\u4ed6\u306e\u30e6\u30fc\u30b6\u30fc\u306b\u7d71\u5408\u3001\u305d\u306e\u3042\u3068\u306a\u3089\u30e6\u30fc\u30b6\u30fc\u3092\u524a\u9664\u3067\u304d\u308b\u3088\u3046\u3060\u3002<\/p>\n<p><a title=\"https:\/\/www.mediawiki.org\/wiki\/Extension:UserMerge\/ja\" href=\"https:\/\/www.mediawiki.org\/wiki\/Extension:UserMerge\/ja\">https:\/\/www.mediawiki.org\/wiki\/Extension:UserMerge\/ja<\/a><\/p>\n<p><\/p>\n<p>\u5c0e\u5165\u3059\u308b\u3068\u3001\u524a\u9664\u3059\u308b\u30e6\u30fc\u30b6\u30fc\u3068\u7d71\u5408\u5148\u30e6\u30fc\u30b6\u30fc\u3092\u6307\u5b9a(\u524a\u9664\u3059\u308b\u5834\u5408\u306f\u30c1\u30a7\u30c3\u30af\u30dc\u30c3\u30af\u30b9\u3092ON)\u3059\u308b\u753b\u9762\u304c\u8868\u793a\u3055\u308c\u308b\u3002<\/p>\n<p><a href=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/07\/mediawiki_merge_user.png\"><img loading=\"lazy\" decoding=\"async\" width=\"497\" height=\"156\" title=\"mediawiki_merge_user\" style=\"display: inline; background-image: none;\" alt=\"mediawiki_merge_user\" src=\"https:\/\/www.typea.info\/blog\/wp-content\/uploads\/2020\/07\/mediawiki_merge_user_thumb.png\" border=\"0\"><\/a><\/p>\n<p><\/p>\n<p>API\u3092\u547c\u3073\u51fa\u3057\u3066\u30da\u30fc\u30b8\u524a\u9664\u3068\u3001Selenium\u3067\u30d6\u30e9\u30a6\u30b6\u3092\u64cd\u4f5c\u3057\u3066\u30e6\u30fc\u30b6\u30fc\u306e\u7d71\u5408\u3068\u524a\u9664\u306e\u64cd\u4f5c\u3092\u884c\u3046\u3084\u3063\u3064\u3051(\u4f7f\u3044\u6368\u3066)C#\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u6210\u3059\u308b\u3002<\/p>\n<p>\u4ee5\u4e0b\u3092NuGet\u3059\u308b<\/p>\n<ul>\n<li>Selenium.WebDriver<\/li>\n<li>Selenium.WebDriver.ChromeDriver<\/li>\n<\/ul>\n<p>\u3042\u3068\u3001Chrome \u3068\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u3042\u3063\u305f\u3001<a href=\"https:\/\/chromedriver.chromium.org\/downloads\">chromedriver_win32<\/a> \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb(\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066PATH\u3092\u901a\u3059)\u304c\u5fc5\u8981\u3002<\/p>\n<p>\u52d5\u304b\u3059\u3068\u3001\u3053\u3093\u306a\u611f\u3058\u306b\u306a\u308b\u3002<\/p>\n<p><\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/jSVJMg9jb6c\" frameborder=\"0\" allowfullscreen=\"\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"><\/iframe><\/p>\n<p><\/p>\n<h4>\u4e0d\u6b63\u306a\u30e6\u30fc\u30b6\u30fc\u306b\u4f5c\u6210\u3055\u308c\u305f\u30da\u30fc\u30b8\u3092\u524a\u9664\u3059\u308b\u3002<\/h4>\n<p>\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u547c\u3073\u51fa\u3059\u3002<\/p>\n<p>\u4f5c\u308a\u3053\u3080\u306e\u304c\u9762\u5012\u3060\u3063\u305f\u306e\u3067\u3001Mediawiki API\u547c\u3073\u51fa\u3057\u306e\u30d1\u30e9\u30e1\u30fc\u30bf(from,to,limit)\u3092\u9069\u5f53\u306b\u5909\u3048\u306a\u304c\u3089\u3001Visual Studio\u304b\u3089\u5b9f\u884c\u3002<\/p>\n<p><\/p>\n<pre class=\"prettyprint\">var api = new MediaWikiApi();\n\n\/\/ \u6709\u52b9\u306a\u30e6\u30fc\u30b6\u30fc\u306e\u30ea\u30b9\u30c8\nvar validUser = new List<string>() { \n    \"Piroto\",\n    \"Xxx\"\n};\napi.DeleteInvalidUserCreatedPages(validUser);<\/string><\/pre>\n<p><\/p>\n<h5>\u540c\u69d8\u306b\u3001\u4e0d\u6b63\u306a\u30e6\u30fc\u30b6\u30fc\u3092\u524a\u9664\u3059\u308b<\/h5>\n<pre class=\"prettyprint\">var api = new MediaWikiApi();\n\/\/ \u6709\u52b9\u306a(\u524a\u9664\u3057\u306a\u3044)\u30e6\u30fc\u30b6\u30fc\nvar validUser = new List<string>() {\n    \"Piroto\",\n    \"Xxx\"\n};\n\napi.DeleteUsers(\"Xxx\", validUser);<\/string><\/pre>\n<p><\/p>\n<p><\/p>\n<pre class=\"prettyprint\">using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing Newtonsoft.Json;\nusing System.Text;\nusing System.IO;\nusing System.Net.Http.Headers;\nusing System.Web;\nusing System.Text.RegularExpressions;\nusing Fsw2Mw.Data;\nusing System.Linq;\nusing OpenQA.Selenium;\nusing OpenQA.Selenium.Edge;\nusing OpenQA.Selenium.Chrome;\nusing System.Threading;\n\nnamespace Fsw2Mw\n{\n    class MediaWikiApi\n    {\n        static readonly string API_URL = @\"https:\/\/yourmediawiki\/api.php\";\n        static readonly string USER_NAME = \"yourid\";\n        static readonly string PASSWORD = \"yourpassword\";\n\n        static readonly HttpClient client = new HttpClient();\n\n        public string Ready()\n        {\n            var loginToken = GetLoginToken();\n            LoginRequest(loginToken);\n            var csrfToken = CsrfToken();\n            return csrfToken;\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ \u6307\u5b9a\u3055\u308c\u305f\u30e6\u30fc\u30b6\u30fc\u304c\u7de8\u96c6\u306b\u304b\u304b\u308f\u3063\u3066\u3044\u306a\u3044\u30da\u30fc\u30b8\u3092\u524a\u9664\u3059\u308b\n        \/\/\/ https:\/\/www.mediawiki.org\/wiki\/API:Allpages\n        \/\/\/ https:\/\/www.mediawiki.org\/wiki\/API:Delete\n        \/\/\/ https:\/\/www.mediawiki.org\/wiki\/API:Properties\n        \/\/\/ &lt;\/summary&gt;\n        public void DeleteInvalidUserCreatedPages(List&lt;string&gt; pValidUsers)\n        {\n            var csrfToken = Ready();\n\n            var validUsers = pValidUsers.Select((s) =&gt; s.ToLower());\n\n            var from = \"N\";\n            var to = from;\n            var limit = 5000;\n\n            string path = $@\"c:\\work\\wiki_delete_info_from_{from}_to_{to}_limit_{limit}.csv\";\n\n            using ( var writer = new StreamWriter(path, false, System.Text.Encoding.GetEncoding(\"shift_jis\")))\n            {\n                writer.WriteLine(\"del,result,pageid,title,users\");\n                var response = client.GetAsync($\"{API_URL}?action=query&amp;format=json&amp;list=allpages&amp;apfrom={from}&amp;apTo={to}&amp;aplimit={limit}\").Result;\n                if (response.StatusCode == System.Net.HttpStatusCode.OK)\n                {\n                    var json = JsonConvert.DeserializeObject&lt;dynamic&gt;(response.Content.ReadAsStringAsync().Result);\n                    var pages = json[\"query\"][\"allpages\"];\n                    foreach(var page in pages)\n                    {\n                        var line = new StringBuilder();\n\n                        Console.WriteLine($\"{page.pageid}\\t{page.title}\");\n                        line.Append($\"\\\"{page.pageid}\\\",\\\"{page.title}\\\"\");\n\n                        var title = page.title;\n                        var response2 = client.GetAsync($\"{API_URL}?action=query&amp;format=json&amp;prop=contributors&amp;titles={title}\").Result;\n                        var json2 = JsonConvert.DeserializeObject&lt;dynamic&gt;(response2.Content.ReadAsStringAsync().Result);\n\n                        bool isDelete = true;\n                        try\n                        {\n                            foreach(var delpage in json2.query.pages)\n                            {\n                                foreach(var editors in delpage)\n                                {\n                                    foreach(var user in editors.contributors)\n                                    {\n                                        string username = user.name;\n                                        if (isDelete &amp;&amp; validUsers.Contains(username.ToLower()))\n                                        {\n                                            isDelete = false;\n                                        }\n                                        line.Append($\",{username}\");\n                                    }\n                                }\n                            }\n                        } catch(Exception)\n                        {\n                            isDelete = false;\n                        }\n\n                        var del = ((isDelete) ? \"DEL\" : \"\");\n                        var delResult = \"\";\n                        if (isDelete)\n                        {\n                            var param = new Dictionary&lt;string, string&gt;()\n                            {\n                                {\"pageid\", $\"{page.pageid}\" },\n                                {\"action\",\"delete\" },\n                                {\"format\",\"json\" },\n                                {\"token\", csrfToken },\n                            };\n                            var content = new FormUrlEncodedContent(param);\n                            var delRes = client.PostAsync($\"{API_URL}\", content).Result;\n                            if (delRes.StatusCode == System.Net.HttpStatusCode.OK)\n                            {\n                                delResult = \"DELETED\";\n                                try\n                                {\n                                    var delContent = delRes.Content.ReadAsStringAsync().Result;\n                                    Console.WriteLine(delContent);\n                                }\n                                catch (Exception) { }\n                            }\n                        }\n                        writer.WriteLine($\"{del},{delResult},\" + line.ToString());\n                    }\n                }\n            }\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ \n        \/\/\/ https:\/\/www.mediawiki.org\/wiki\/Extension:UserMerge\/ja\n        \/\/\/ &lt;\/summary&gt;\n        \/\/\/ &lt;param name=\"mergeUser\"&gt;&lt;\/param&gt;\n        internal void DeleteUsers(string mergeUser, List&lt;string&gt; pValidUsers)\n        {\n\n            var deleteUsers = GetAllUsers(pValidUsers,500);\n\n            \n            var driver = new ChromeDriver();\n\n            \/\/ \u30ed\u30b0\u30a4\u30f3\u30da\u30fc\u30b8\n            driver.Navigate().GoToUrl(\"https:\/\/yourmediawiki\/index.php?title=%E7%89%B9%E5%88%A5:%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3&amp;returnto=%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8\");\n            var loginUser = driver.FindElementByName(\"wpName\");\n            loginUser.SendKeys(USER_NAME);\n            var passwd = driver.FindElementByName(\"wpPassword\");\n            passwd.SendKeys(PASSWORD);\n            var loginButton = driver.FindElementByName(\"wploginattempt\");\n            loginButton.Click();\n\n            Thread.Sleep(2000);\n\n            foreach (var deleteUser in deleteUsers)\n            {\n                \/\/ \u30e6\u30fc\u30b6\u30fc\u7d71\u5408\u3068\u524a\u9664\n                driver.Navigate().GoToUrl(\"https:\/\/yourmediawiki\/index.php\/%E7%89%B9%E5%88%A5:%E5%88%A9%E7%94%A8%E8%80%85%E3%81%AE%E7%B5%B1%E5%90%88\");\n                var spamUserText = driver.FindElementByName(\"wpolduser\");\n                spamUserText.SendKeys(deleteUser);\n                var mergeUserText = driver.FindElementByName(\"wpnewuser\");\n                mergeUserText.SendKeys(mergeUser);\n                var checkDelete = driver.FindElementByName(\"wpdelete\");\n                checkDelete.Click();\n\n                mergeUserText.SendKeys(Keys.Enter);\n\n                Thread.Sleep(2000);\n            }\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ https:\/\/www.mediawiki.org\/wiki\/API:Allusers\n        \/\/\/ &lt;\/summary&gt;\n        public List&lt;string&gt; GetAllUsers(List&lt;string&gt; pExcludeUsers, int limit)\n        {\n            var result = new List&lt;string&gt;();\n            var excludeUsers = pExcludeUsers.Select((s) =&gt; s.ToLower());\n\n            var response = client.GetAsync($\"{API_URL}?action=query&amp;format=json&amp;list=allusers&amp;aulimit={limit}\").Result;\n            if (response.StatusCode == System.Net.HttpStatusCode.OK)\n            {\n                var json = JsonConvert.DeserializeObject&lt;dynamic&gt;(response.Content.ReadAsStringAsync().Result);\n                foreach(var user in json.query.allusers)\n                {\n                    var userName = $\"{user.name}\";\n                    \/\/ \u6b63\u5e38\u30e6\u30fc\u30b6\u30fc\u306f\u9664\u5916\n                    if (!excludeUsers.Contains(userName.ToLower()))\n                    {\n                        result.Add(userName);\n                    }\n                }\n            }\n            return result;\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ 003.CSRF\u30c8\u30fc\u30af\u30f3\u306e\u53d6\u5f97\n        \/\/\/ &lt;\/summary&gt;\n        private string CsrfToken()\n        {\n            var param = new Dictionary&lt;string, string&gt;()\n            {\n                { \"action\", \"query\" },\n                {\"meta\",\"tokens\" },\n                {\"format\",\"json\" },\n            };\n\n            var response = client.GetAsync($\"{API_URL}?{new FormUrlEncodedContent(param).ReadAsStringAsync().Result}\").Result;\n            if (response.StatusCode == System.Net.HttpStatusCode.OK)\n            {\n                var json = JsonConvert.DeserializeObject&lt;dynamic&gt;(response.Content.ReadAsStringAsync().Result);\n                var crsftoken = $\"{json.query.tokens.csrftoken}\";\n                Console.WriteLine($\"CRSF TOKEN={crsftoken}\");\n                return crsftoken;\n            }\n            else\n            {\n                throw new Exception(\"GetLoginToke Error\");\n            }\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ 002.\u30ed\u30b0\u30a4\u30f3\n        \/\/\/ &lt;\/summary&gt;\n        \/\/\/ &lt;param name=\"loginToken\"&gt;&lt;\/param&gt;\n        public void LoginRequest(string loginToken)\n        {\n            var param = new Dictionary&lt;string, string&gt;()\n            {\n                {\"action\", \"login\" },\n                {\"lgname\", USER_NAME},\n                {\"lgpassword\",PASSWORD },\n                {\"lgtoken\",loginToken },\n                {\"format\",\"json\" },\n            };\n\n            var response = client.PostAsync(API_URL, new FormUrlEncodedContent(param)).Result;\n            if (response.StatusCode == System.Net.HttpStatusCode.OK)\n            {\n                var json = JsonConvert.DeserializeObject&lt;dynamic&gt;(response.Content.ReadAsStringAsync().Result);\n                Console.WriteLine(json);\n            }\n            else\n            {\n                throw new Exception(\"LoginRequest Error\");\n            }\n        }\n\n        \/\/\/ &lt;summary&gt;\n        \/\/\/ 001.\u30ed\u30b0\u30a4\u30f3\u30c8\u30fc\u30af\u30f3\u306e\u53d6\u5f97\n        \/\/\/ &lt;\/summary&gt;\n        public string GetLoginToken()\n        {\n            var param = new Dictionary&lt;string, string&gt;()\n            {\n                {\"action\", \"query\" },\n                {\"meta\",\"tokens\" },\n                {\"type\",\"login\" },\n                {\"format\",\"json\" },\n            };\n\n            var response = client.GetAsync($\"{API_URL}?{new FormUrlEncodedContent(param).ReadAsStringAsync().Result}\").Result;\n            if (response.StatusCode == System.Net.HttpStatusCode.OK)\n            {\n                var json = JsonConvert.DeserializeObject&lt;dynamic&gt;(response.Content.ReadAsStringAsync().Result);\n                var logintoken = $\"{json.query.tokens.logintoken}\";\n                Console.WriteLine($\"LOGIN TOKEN={logintoken}\");\n                return logintoken;\n            } \n            else\n            {\n                throw new Exception(\"GetLoginToke Error\");\n            }\n        }\n    }\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Mediawiki\u306b\u4e0d\u6b63\u30a2\u30af\u30bb\u30b9\u3055\u308c\u3066\u5bfe\u51e6\u3057\u305f\u306e\u3060\u304c\u3001\u306a\u304b\u306a\u304b\u9762\u5012\u3060\u3063\u305f\u306e\u3067\u3001\u4eca\u5f8c\u306e\u305f\u3081\u306b\u30e1\u30e2\u3002 1.Mediawiki \u306b\u4f55\u5343\u4eba\u3082\u306e\u4e0d\u6b63\u30e6\u30fc\u30b6\u30fc\u304c\u4f5c\u6210\u3055\u308c\u305f\u3002\u3002\u3002 FreeStyleWiki \u304b\u3089 Mediawiki\u306b [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","sitemap_hide":"","_veu_custom_css":"","veu_display_promotion_alert":"","vkexunit_cta_each_option":"","footnotes":""},"categories":[114],"tags":[],"class_list":["post-805","post","type-post","status-publish","format-standard","hentry","category-mediawiki"],"veu_head_title_object":{"title":"","add_site_title":""},"_links":{"self":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/805","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=805"}],"version-history":[{"count":1,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/805\/revisions"}],"predecessor-version":[{"id":806,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/posts\/805\/revisions\/806"}],"wp:attachment":[{"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=805"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=805"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.typea.info\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=805"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}