public Salestate[] GetSalestates() { var http_salestate_list_url = "https://creator.toranoana.jp/portal/salestate_list.cgi"; var salestate_page_key = "salestate_page"; WebClientEx webClient = new WebClientEx(); webClient.CookieContainer = Cookie; // 売上ページ一覧を取得 var buffer = webClient.DownloadData(http_salestate_list_url); var htmlString = ConvertHtmlBufferToString(buffer); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(htmlString); // 売上ページのみへのリンク取得 var saleStateLinks = doc.DocumentNode.SelectNodes("//a").Where(_=>_.GetAttributeValue("href", "").Contains(salestate_page_key)); var baseURI = new Uri(http_salestate_list_url); List<Salestate> salestates = new List<Salestate>(); foreach (var link in saleStateLinks) { // 売上ページを走査 var uri = new Uri( baseURI, link.GetAttributeValue("href", "")); salestates.Add(GetSalestate(webClient, uri.ToString())); } return salestates.ToArray(); }
Salestate GetSalestate(WebClientEx webClient, string url) { var re_ym = "ym=.*"; var buffer = webClient.DownloadData(url); var htmlString = ConvertHtmlBufferToString(buffer); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(htmlString); Salestate salestate = new Salestate(); // 年月 { var match = Regex.Match(url, re_ym); var value = match.Value.Replace("ym=", ""); salestate.Year = int.Parse(value) / 100; salestate.Month = int.Parse(value) % 100; } // 売上 var item_list = doc.DocumentNode.SelectNodes("//table[@class='item_list']"); var items_ = new List<Salestate.Item>(); var commission_ = new List<Salestate.Commission>(); foreach (var items in item_list) { var trs = items.ChildNodes.Where(_ => _.Name == "tr").ToArray(); foreach(var tr in trs) { var tds = tr.ChildNodes.Where(_ => _.Name == "td"); if (tds.Any(_ => _.Attributes["class"].Value == "sum")) { // 消費税と商品で異なる。 // 商品の合計しか出力されていなかった時期がある。 var number = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["colspan"].Value == "2")?.InnerText); if (tds.Any(_ => _.InnerText.Contains("商品小計"))) { salestate.SyouhinSum = number; } else if (tds.Any(_ => _.InnerText.Contains("消費税小計"))) { salestate.SyouhizeiSum = number; } else if (tds.Any(_ => _.InnerText.Contains("手数料合計"))) { salestate.TesuuryouSum = number; } else { salestate.Sum = number; } } else if (tds.Any(_ => _.Attributes["class"].Value == "remittance_sum")) { salestate.RemittanceSum = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["colspan"].Value == "2")?.InnerText); } else { var cols1 = tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols1")?.InnerText; if(cols1 == "手数料") { Salestate.Commission item = new Salestate.Commission(); item.Name = tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols2")?.InnerText; item.Cost = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols8")?.InnerText); commission_.Add(item); } else { // 通常 Salestate.Item item = new Salestate.Item(); item.Name = tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols2")?.InnerText; item.Oroshine = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols3")?.InnerText); item.SengetsuZaiko = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols4")?.InnerText); item.Nouhin = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols5")?.InnerText); item.KongetsuZaiko = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols6")?.InnerText); item.Uriage = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols7")?.InnerText); item.Remittance = ParseNumber(tds.FirstOrDefault(_ => _.Attributes["class"].Value == "cols8")?.InnerText); if (item.Name != null) { items_.Add(item); } } } } } salestate.Items = items_.ToArray(); salestate.Commissions = commission_.ToArray(); return salestate; }