Web ページでは、ブラウザーのセキュリティにより、その Web ページを提供したドメインと異なるドメインに対して要求を行うことはできません。
ではクロスオリジン要求 (CORS) が許可されていないAPIに対してはどうすればよいのでしょうか?
ここではYahoo!!日本語形態素解析を使います。そのままではうまくいきません。
そこでサイト内にPHPファイルをアップロードしてそこでAPIを呼び出してこれを取得するという方法でやってみることにします(だったら全部PHPでやればいいじゃんという話になってしまうのですが・・・)。
完成品の確認はこちらからどうぞ。
https://lets-csharp.com/wp-content/uploads/2021/02/blazor-app-morphological-analysis/
入力された文章を分解して、形態素の表記、読みがな、品詞、基本形を取得します。リクエストパラメータについてはテキスト解析:日本語形態素解析 – Yahoo!デベロッパーネットワークを参照してください。
wwwroot/sample-data/abc.php
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php $sentence = $_POST["Sentence"]; $filter = $_POST["Filter"]; $appid = 'アプリケーションIDはご自身で取得してください'; $url = "http://jlp.yahooapis.jp/MAService/V1/parse?appid=".$appid."&results=ma"; $url .= "&sentence=".urlencode($sentence); $url .= "&filter=".urlencode($filter); $url .= "&response=".urlencode("surface,reading,pos,baseform"); $homepage = file_get_contents($url); echo $homepage; ?> |
1ページしかつくらないのでNavMenu.razorのいらない部分は消してしまいます。
NavMenu.razor
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="top-row pl-4 navbar navbar-dark"> <a class="navbar-brand" href="">Yahoo!!日本語形態素解析</a> </div> <div> <ul class="nav flex-column"> <li class="nav-item px-3"> <NavLink class="nav-link" href=""> <span class="oi oi-home" aria-hidden="true"></span> Home </NavLink> </li> </ul> </div> |
wwwroot/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>Yahoo!!日本語形態素解析</title> <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> <link href="css/app.css" rel="stylesheet" /> </head> <body> <app>Loading...</app> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="" class="reload">Reload</a> <a class="dismiss">??</a> </div> <script src="_framework/blazor.webassembly.js"></script> </body> </html> |
Pages/Index.razorは以下のようにします。
取得したい品詞にチェックをいれてテキストエリアに解析したい文章を入力してボタンをおすと解析結果が表示されます。
ボタンをおすとHandleValidSubmit()メソッドが実行されます。どのテキストエリアのテキストとチェックボックスの状態をパラメータにしてHttp.PostAsyncメソッドが呼び出されます。処理の結果としてXmlが返されるので、これをGetResultFromXml(string xml)メソッドで解析してWordオブジェクトのリストを取得しています。
Pages/Index.razor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
@page "/" @inject HttpClient Http <h1>Yahoo!!日本語形態素解析</h1> <p>Yahoo!!日本語形態素解析で文章の解析をおこないます。</p> <p>@str</p> @if (Words.Count != 0) { <table class="table"> <thead> <tr> <th>表記</th> <th>よみ</th> <th>品詞</th> <th>基本形</th> </tr> </thead> <tbody> @foreach (var word in Words) { <tr> <td>@word.Surface</td> <td>@word.Reading</td> <td>@word.Pos</td> <td>@word.Baseform</td> </tr> } </tbody> </table> } <textarea id="text1" rows="10" cols="60" @bind="@Sentence"></textarea> <br /> <input type="checkbox" @bind="@Filter1" />1 : 形容詞 <br /> <input type="checkbox" @bind="@Filter2" />2 : 形容動詞 <br /> <input type="checkbox" @bind="@Filter3" />3 : 感動詞 <br /> <input type="checkbox" @bind="@Filter4" />4 : 副詞 <br /> <input type="checkbox" @bind="@Filter5" />5 : 連体詞 <br /> <input type="checkbox" @bind="@Filter6" />6 : 接続詞 <br /> <input type="checkbox" @bind="@Filter7" />7 : 接頭辞 <br /> <input type="checkbox" @bind="@Filter8" />8 : 接尾辞 <br /> <input type="checkbox" @bind="@Filter9" />9 : 名詞 <br /> <input type="checkbox" @bind="@Filter10" />10 : 動詞 <br /> <input type="checkbox" @bind="@Filter11" />11 : 助詞 <br /> <input type="checkbox" @bind="@Filter12" />12 : 助動詞 <br /> <input type="checkbox" @bind="@Filter13" />13 : 特殊(句読点、カッコ、記号など) <br /> <button @onclick="HandleValidSubmit">解析</button> <!-- Begin Yahoo! JAPAN Web Services Attribution Snippet --> <a href="http://developer.yahoo.co.jp/about"> <img src="http://i.yimg.jp/images/yjdn/yjdn_attbtn2_105_17.gif" width="105" height="17" title="Webサービス by Yahoo! JAPAN" alt="Webサービス by Yahoo! JAPAN" border="0" style="margin:15px 15px 15px 15px"> </a> <!-- End Yahoo! JAPAN Web Services Attribution Snippet --> @code { public string Sentence = "解析したい文章を入力してください。"; public string str = ""; public bool Filter1 = true; public bool Filter2 = true; public bool Filter3 = true; public bool Filter4 = true; public bool Filter5 = true; public bool Filter6 = true; public bool Filter7 = true; public bool Filter8 = true; public bool Filter9 = true; public bool Filter10 = true; public bool Filter11 = true; public bool Filter12 = true; public bool Filter13 = true; public class Word { public string Surface = ""; public string Reading = ""; public string Pos = ""; public string Baseform = ""; } private List<Word> Words = new List<Word>(); private async Task HandleValidSubmit() { List<string> filters = new List<string>(); if (Filter1) filters.Add("1"); if (Filter2) filters.Add("2"); if (Filter3) filters.Add("3"); if (Filter4) filters.Add("4"); if (Filter5) filters.Add("5"); if (Filter6) filters.Add("6"); if (Filter7) filters.Add("7"); if (Filter8) filters.Add("8"); if (Filter9) filters.Add("9"); if (Filter10) filters.Add("10"); if (Filter11) filters.Add("11"); if (Filter12) filters.Add("12"); if (Filter13) filters.Add("13"); if (Sentence == "") { str = "エラー:解析する文章を入力してください。"; return; } if (Sentence.Length > 10000) { str = "エラー:解析できる文章は10000字までです。"; return; } if (filters.Count == 0) { str = "エラー:取得する品詞にチェックをつけてください。"; return; } string filter = String.Join("|", filters.ToArray()); var parameters = new Dictionary<string, string>() { { "Sentence", Sentence }, { "Filter", filter }, }; var content = new FormUrlEncodedContent(parameters); var res = await Http.PostAsync("sample-data/abc.php", content); Task<string> task = res.Content.ReadAsStringAsync(); string ret = task.Result; GetResultFromXml(ret); str = ""; } void GetResultFromXml(string xml) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(xml); var nodes = doc.SelectNodes("//*[local-name()='word']"); Words = new List<Word>(); foreach (System.Xml.XmlNode node in nodes) { System.Xml.XmlNode node1 = node.SelectSingleNode("*[local-name()='surface']"); System.Xml.XmlNode node2 = node.SelectSingleNode("*[local-name()='reading']"); System.Xml.XmlNode node3 = node.SelectSingleNode("*[local-name()='pos']"); System.Xml.XmlNode node4 = node.SelectSingleNode("*[local-name()='baseform']"); Word word = new Word(); if (node1 != null) word.Surface = node1.InnerText; if (node2 != null) word.Reading = node2.InnerText; if (node3 != null) word.Pos = node3.InnerText; if (node4 != null) word.Baseform = node4.InnerText; Words.Add(word); } } } |
完成品の確認はこちらからどうぞ。
https://lets-csharp.com/wp-content/uploads/2021/02/blazor-app-morphological-analysis/