C#でスクレイピングをする場合の基本的なやり方について紹介します。
スクレイピングとは、ネットのページなどを読み込んで必要なデータを抽出することです。APIが提供されていれば楽ですが、そうでない場合は直接ページ上のファイルをダウンロードして分析させることになります。
C#でスクレイピング
ネットのページから情報を取得するには、大きく分けて「サーバから行う方法」と「自分のPCから行う方法」があります。
「サーバから行う方法」とは、レンタルサーバなどでPHPなどでプログラムを書きCronで定期的に実行するというものです。
サーバは24時間動いていますので継続的な作業ができる反面、レンタルサーバの仕様によってはCronできる回数などが制限される場合があります。
「自分のPCから行う方法」では、VisualStudioでスクレイピング用プログラムを作って動かしたりします。
レンタルサーバーのような制限はありませんが、パソコンをずっと立ち上げていないと動作しません。
ここではVisualStudioのC#でスクレイピングをする場合の基本的なやり方について紹介していきます。
C#でスクレイプする場合、「ネット上のページをダウンロードすること」「ダウンロードしたファイルから特定の情報を抜き出す」「抜き出した情報を記録する」というのが基本的な工程となります。
ネット上のページをダウンロードする
C#では、URLを指定してダウンロードできる機能があります。
【Visual Studio 2019】C#でインターネット関数の使い方 - 困ったー
「System.Net.WebClient」を使い、「DownloadFile」関数を利用します。
ダウンロードするファイルのURLとダウンロード後にパソコン内に格納されるファイルのパスを指定します。
以下は「https://komatter.com/index.php」を「c:\temp.txt」として保存するプログラムになります。
System.Net.WebClient wc = new System.Net.WebClient();
try
{
wc.DownloadFile("https://komatter.com/index.php", @"c:\temp.txt");
}
catch (Exception ex)
{
MessageBox.Show("エラー!" + ex.ToString());
}
finally
{
wc.Dispose();
}
無事ダウンロードできれば、temp.txtに以下のようなページのソースが入っているはずです。
<!doctype html>
<html lang="ja"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>こまったー</title><meta name="description" content="情報ブログ「困ったー」などを運営する「こまったー」の公式サイト兼ツール置き場です。" /><link rel="canonical" href="https://komatter.com/index.php" /><meta name="msvalidate.01" content="C1EBA7B2A3820FFAEA4643A0C6E819C7" /><meta property="og:title" content="こまったー"><meta property="og:site_name" content="komatter.com" /><meta property="og:type" content="website" /><meta property="og:description" content="情報ブログ「困ったー」などを運営する「こまったー」の公式サイト兼ツール置き場です。" /><link rel="shortcut icon" href="//komatter.com/img/favicon.ico" />
<style>.....
文字を抜き出す
ダウンロードしたファイルから特定の文字を抜き出します。
文字を抜き出すには正規表現とういものを利用します。C#では「System.Text.RegularExpressions」というオブジェクトが利用できます。
抜き出すルールを書いて、それをもとに文字を抽出します。しかしルールの書き方は結構面倒ですので、最初はシンプルな書き方から慣れていくほうがいいと思います。
タグに挟まれた文字
HTMLソースでは「<h1>ほにゃらら</h1>」のように記述されています。
例えば「<h1>」と「</h1>」ではさまれたところを抽出したい場合、「<h1>(.*?)</h1>」というふうにルールを記述すれば特定の文字で挟まれた箇所を抽出できます。
String sSrc = "abc<h1>ok</h1>def";
String sPattern = @"<h1>(.*?)</h1>";System.Text.RegularExpressions.MatchCollection mc =
System.Text.RegularExpressions.Regex.Matches(
sSrc, sPattern);string sResult = "";
foreach (System.Text.RegularExpressions.Match m in mc)
{
sResult += m.Value + "\r\n";
}
textBox1.Text = sResult;
固定の数字(郵便番号)
郵便番号は「001-0001」のように「3桁の数値、ハイフン、4桁の数値」という書き方ですので「 \d\d\d-\d\d\d\d」というパターンで調べることができます。「\d」は数字を表します。
String sSrc = "郵便番号は123-1234です";
String sPattern = @"\d\d\d-\d\d\d\d";System.Text.RegularExpressions.MatchCollection mc =
System.Text.RegularExpressions.Regex.Matches(
sSrc, sPattern);string sResult = "";
foreach (System.Text.RegularExpressions.Match m in mc)
{
sResult += m.Value;
}
textBox1.Text = sResult;
桁数の変わる数字を抽出(電話番号)
電話番号は「03-1234-1234」もあれば「090-1234-1234」もあります。
ハイフンで3つの数値文字列をつなぐのですが、郵便番号と違って桁数が違う場合も考えないといけません。
「\d{1,4}」のように書くと、数値が1~4回繰り返していることを指示できます。
電話番号を簡単に調べるには「\d{1,4}-\d{1,4}-\d{1,4}」と書けば、4桁以内の数値文字をハイフンでつないだものとして探すことができます。
Strin
g sSrc = "電話は03-1234-5678と0111-1111-1111です";
String sPattern = @"\d{1,4}-\d{1,4}-\d{1,4}";System.Text.RegularExpressions.MatchCollection mc =
System.Text.RegularExpressions.Regex.Matches(
sSrc, sPattern);string sResult = "";
foreach (System.Text.RegularExpressions.Match m in mc)
{
sResult += m.Value + "\r\n";
}
textBox1.Text = sResult;
定期的に実行する
プログラムができたら最後は一定時間おきに実行してみましょう。
簡単なのはタイマーを使った実装です。
ツールボックスからタイマーを選んでフォームへ配置します。
EnabledをTrueにし、Intervalを設定します。
1時間おきならIntervalを3600にします。