はじめに
特定のサイトのお知らせ欄が更新されたかな?と毎回見に行くのが面倒だったのでスクレイピングしてメールを送ってくれるバッチ処理を作ってみました。
色々ライブラリを調べてみるとAngleSharpというライブラリが便利そうだったのでこちらを使って実装してみました。
AngleSharpについての記事は以下がとても分かりやすかったです!ありがとうございます!!!
※メールサーバについてはGmailの無料メールサーバを利用しました。
サンプルコード
今回はサクッと作ったので対象のサイトやメールサーバの情報などはソースコード上にべた書きです。
ちゃんと作る場合はここらへんは外部ファイルにした方が良いと思います。
あとは一つのクラス内にドカッと書いてしまっているのもあれな気がするけどお許しを...。
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace ScrapingApp
{
class Program
{
private static readonly HttpClient _client = new();
static async Task Main()
{
var urlstring = "スクレイピングしたいサイトのURL";
using var stream = await _client.GetStreamAsync(new Uri(urlstring));
var parser = new HtmlParser();
// 指定したサイトのHTMLをストリームで取得する
IHtmlDocument doc = await parser.ParseDocumentAsync(stream);
// 以下から★部分までは僕の取得したかった情報を取得するためにセットしている
// だけなのでここら辺は取得したい内容によって変わるかと思います。
var tdElements = doc.GetElementById("Id名").QuerySelectorAll("セレクタ");
var yearStr = DateTime.Now.Year.ToString();
// メールのBodyに入れる内容をStringBuilderへ入れていきます。
StringBuilder sb = new();
foreach (var tr in tdElements)
{
// 今回のサイトでは年が表示されていなかったので追加しています。
var dttmText = $"{yearStr}/{tr.QuerySelector("セレクタ").TextContent}";
// 1日前からアプリ実行までの期間内に更新された内容があればメールの本文に追加します。
// 今回はテキストとURL(href)をメールで送ります。
if (DateTime.Now.AddDays(-1).CompareTo(DateTime.Parse(dttmText)) > 0)
break;
sb.AppendLine($"{tr.QuerySelector("セレクタ").TextContent} 投稿日付:{dttmText}");
sb.AppendLine(tr.QuerySelector("セレクタ").GetAttribute("href"));
}
// ★
// ここからはMailKitというライブラリを用いてメールを送る処理を行っています。
var message = new MimeKit.MimeMessage();
message.From.Add(new MimeKit.MailboxAddress("メール送信元の名前", "メール送信元のアドレス"));
message.To.Add(new MimeKit.MailboxAddress("メール送信先の名前", "メール送信先のアドレス"));
message.Subject = "〇〇通知を送ります~~";
var textPart = new MimeKit.TextPart(MimeKit.Text.TextFormat.Plain)
{
Text = string.IsNullOrEmpty(sb.ToString())
? "新規〇〇探しにいったけどなかった(;´∀`)\n無駄にメール送ってごめんねm(__)m"
: sb.ToString()
};
message.Body = textPart;
using var client = new MailKit.Net.Smtp.SmtpClient();
try
{
await client.ConnectAsync("smtp.gmail.com", 587);
await client.AuthenticateAsync("Gmailのメールアドレス", "Gmailのアカウントパスワード");
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
と、これをタスクスケジューラにセットして毎日7時と18時に送られてくるのを待つ...と。
おわりに
それにしてもこんな簡単にスクレイピングできちゃうなんてAngleSharp良いですね!!
もし業務でスクレイピングする機会があればこのライブラリを使ってみよう~~!!
2021/09/23追記
こちらですが、最終的にはリファクタリングしたり機能追加したりして以下のようになりました~~。
(メールからLINEになったり、ローカルPCのタスクスケジューラではなくてAWS上に配置したり...)