見出し画像

C#で出●館インセンティブ情報を通知するbot作ってみた③

押忍!

某youtuberの登場キャラでおなじみ残心ニキこと「鎖骨打ちのサトJ」です!

前の記事

の続きです。

最近は特にネタはないのですが強いていうなら来月(10月)に受ける応用情報の勉強全然やってなくて受かる気がしません。

基本情報の時みたいなやる気がでなくて困ってますw

もともと資格勉強は勉強するテーマがないときにやるくらいの意気込みだったんで今は資格勉強よりASP.NET MVCの勉強してます

今日のテーマは前回の記事のフローチャートのこの部分

の解説です

■スクレイピングする実際のWeb画面操作

ここからは実際にインセンティブサイトにアクセスしてスクレイピングしますが簡単にどういう操作をWeb画面では行っているかを説明します

  1. 出前館インセンティブサイトにアクセス

  2. 日にちと地域と都道府県を選択

  3. 選択した都道府県のインセンティブ情報が表示される

この動作をプログラミングで書いていきます

ライブラリはSeleniumを使います

Seleniumの主要メソッド等はこちらの記事を参考にしてください

下記記事はPythonで書いてますがC#も似た感じです

■インセンティブ情報を表示させる

②の処理をプログラミングで書いてみます
とりあえずコード載せます

Driver.Navigate().GoToUrl("https://cdn.demae-can.com/contents/driver/boost/area/index.html");
Driver.FindElement(By.Id("datepicker")).Clear();
Driver.FindElement(By.Id("datepicker")).SendKeys(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd"));
new SelectElement(Driver.FindElement(By.Id("area"))).SelectByText(area);
new SelectElement(Driver.FindElement(By.Id("prefecture"))).SelectByText(prefecture);

1行目で出前館インセンティブサイトにアクセスします

2行目3行目で日付を入力してます。
日付欄はデフォルトで値が入っており、選択できるようになっているが入力も可能になっています

なんでまず入力欄をクリアして日付を入力してます。

日付は実行処理日の次の日を指定しています。

4行目で地域、5行目で都道府県を選択してます。

選択型のエレメントをいじるのはnew SelectElementを使います

■インセンティブ情報を取得する

②の処理が終わると③の部分が表示されるようになります。

③の部分の情報をDictonary形式(Map)で格納します。

var dic = new Dictionary<string, string>();
//(○○時 : 1.○)

あえてString型にしたのは稼働時間外の表記が[-]のためです。

とりあえず全体のコード載せます。

var table = Driver.FindElement(By.Id("resultmap"));
var thead = table.FindElement(By.Id("resulthead"));
var columns = thead.FindElements(By.TagName("th"));
var tbody = table.FindElement(By.Id("resultbody"));
var rows = tbody.FindElements(By.TagName("tr"));
var dic = new Dictionary<string, string>();
foreach (var row in rows)
{
    var td = row.FindElements(By.TagName("td"));
    //column[0]は市区町村
    if (td[0].Text != city) { continue; }
    //td[0]とcolumn[0]は読み取らない
    for (int i =1;i<td.Count;i++)
    {
        dic.Add(columns[i].Text, td[i].Text);
    }
    if(dic.Count > 0) { break; }
}

③の部分はTableタグになっているのでイメージとしてはテーブル内をループして目的のエリアの情報だけ取っていく形です

1-4行目で③の部分のHtml情報を取ってきます

実際にループで使う情報は画面でいうここです

行が5行目で列がループ内の8行目です

7行目以降で行をループして指定した市区町村を探して、指定した市区町村の行にたどり着いたら今度は列をループして「○○時 : 1.○」みたいな感じで情報を格納していきます

■なんで市区町村を選択しなかったのか

普段から見てる人ならすぐ気づいたかもしれませんが市区町村まで選択したら③の箇所には指定した市区町村のみ表示されます

ここまで選択すれば行を探すループ処理いらないんじゃね?って思う人もいるかと思います。

ではなんでそれをしなかったのか

それは指定した市区町村以外表示されないのは
行が存在しないのではなく、行の表示をプロパティで消しているから

です

これが③の部分のHtml情報なんですが

画面では表示されていない中央区のデータもHtml上では存在しております。

しかし、Cssでdisplay:noneを指定することで表示させないようにしてます。

なのでどっちにしろループ処理は必要なんで市区町村を選択する処理は無駄なんでしていないって感じです。

どうしてもループさせたくないのでしたらXPathで取得もやろうと思えばできるとは思いますが私はtdタグのIDの規則性がよくわからなかったのでやめました

XPathとは

終わりに

いかがでしょうか?

出前館のサイトは以前やってたAmazonより作りが簡単なのとBot対策が甘いんで楽に取得できました

次回は取得した情報を加工してLineする処理の解説になります


この記事が気に入ったらサポートをしてみませんか?