C# 8.0でHTMLのスクリプト要素の一部をJSONとして抜き出す方法の覚書です。この投稿ではSystem.Text.Json.JsonDocumentクラスを用いて不定形のJSONを扱います。スクリプト要素の一部がJSONの規則を満たさない場合は扱えないことに注意してください。なお、定形のJSONを構造体などとして扱う場合はSystem.Text.Json.JsonSerializerクラスを使用してください。
HTMLファイルの特定のSCRIPT要素からJSONを抜き出して参照する
usingSystem.Linq;usingSystem.Text.Json;usingAngleSharp.Html.Dom;// AngleSharpをインストールしてください。usingAngleSharp.Html.Parser;namespaceConsoleApp1{classProgram{staticvoidMain(){varsource="<html><head><script src=\"\"></script></head><body>"+"<script src=\"\"></script>"+"<script defer>let x = {\"abc\":\"abc\", \"def\":false, \"ghi\": false, \"items\":{\"data1\": 0, \"data2\": \"value\", \"data3\": [0, 1, 2], \"data4\":{ \"data41\": 41}}, \"xyz\": false};</script>"+"<script>var y = 0;</script></body></html>";varparser=newHtmlParser();// TODO:ここでHTMLを読み込みます。// 必要に応じてファイルやインターネットから読み込んでください。vardoc=default(IHtmlDocument);doc=parser.ParseDocument(source);// TODO:ここで目的のSCRIPT要素を取得します。// ここではBODY要素子孫でdefer属性を持つSCRIPT要素を取得します。varscriptElements=doc.QuerySelectorAll("body script[defer]");if(scriptElements.Length!=1){return;}// TODO:ここでは前後が不変であると仮定してitems部分をJSONとして抜き出します。// head、tail、i1、i2の内容は取得する内容に合わせて調整してください。varscriptElementData=scriptElements.First().TextContent;varheadString="\"def\":false, \"ghi\": false, \"items\":{\"data1\":";vartailString="}, \"xyz\": false";vari1=scriptElementData.IndexOf(headString)+"\"def\":false, \"ghi\": false, ".Length;vari2=scriptElementData.IndexOf(tailString,i1+headString.Length);// 今回は"}"を含めない// TODO:JSONが正常に抜き出せたかをここで確認してください。// JSONではキーにも前後の「"」が必要なことに注意してください。varjsonRaw="{"+scriptElementData.Substring(i1,i2-i1+1)+"}";varjsonDoc=JsonDocument.Parse(jsonRaw);//varitems=jsonDoc.RootElement.GetProperty("items");varitemsRawText=items.GetRawText();// {"data1": 0, "data2": "value", "data3": [0, 1, 2], "data4":{ "data41": 0}}varitemsPropNames=items.EnumerateObject().Select(prop=>prop.Name).ToArray();// string[4] {"data1", "data2", "data3", "data4"}vardata1=items.GetProperty("data1");// ValueKind = Number : "0"vardata4=items.GetProperty("data4");// ValueKind = Object : "{ "data41": 41}"vardata41=items.GetProperty("data4").GetProperty("data41");// ValueKind = Number : "41"}}}