【C#】Selenium ChromeDriverを使ってWebスクレイピング

必要なパッケージのインストール

まずは、NuGetから以下の二つのパッケージをインストールします。

  • Selenium.WebDriver
  • Selenium.WebDriver.ChromeDriver

特定のURLを開いて待機する

using System;
using System.IO;
using System.Reflection;
using OpenQA.Selenium.Chrome;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var chrome = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
            chrome.Url = "http://google.com/";

            Console.ReadKey();
            chrome.Quit();
        }
    }
}

入力フォームに値を入力して送信する

// input要素に入力
chrome.FindElementByName("inputのName").SendKeys("test");
// 送信
chrome.FindElementByName("formのName").Submit();

Select要素を操作する

追加のパッケージが必要になるため、NuGetでSelenium.Supportをインストールしてください。

using OpenQA.Selenium.Support.UI;
...

var select = chrome.FindElementByName("selectのname");
var se = new SelectElement(select);
se.SelectByValue("10");

特定の要素の値を取得する

// 要素のIDを使って取得
var value = chrome.FindElementById("要素のID").Text;

// 要素のClassを使って取得(一番最初に見つかった要素)
var value = chrome.FindElementByClassName("要素のClass").Text;

特定の要素を検索するメソッドはこれらを含め以下のようなものがあります。

  • FindElementByClassName(string className)
    • クラス名から要素を検索
  • FindElementByCssSelector(string cssSelector)
    • CSSセレクタを使って要素を検索
  • FindElementById(string id)
    • ID名から要素を検索
  • FindElementByLinkText(string linkText)
    • リンクテキストから要素を検索
  • FindElementByName(string name)
    • name属性から要素を検索
  • FindElementByPartialLinkText(string partialLinkText)
    • ?
  • FindElementByTagName(string tagName)
    • タグ名から要素を検索
  • FindElementByXPath(string xpath)
    • XPathを使って要素を検索

複数要素を検索する場合は以下のメソッドを使用します。

  • FindElementsByClassName(string className)
  • FindElementsByCssSelector(string cssSelector)
  • FindElementsById(string id)
  • FindElementsByLinkText(string linkText)
  • FindElementsByName(string name)
  • FindElementsByPartialLinkText(string partialLinkText)
  • FindElementsByTagName(string tagName)
  • FindElementsByXPath(string xpath)

特定の要素をクリックする

// IDを使って要素をクリック
chrome.FindElementById("要素のID").Click();

// Classを使って要素をクリック(一番最初に見つかった要素)
chrome.FindElementByClassName("要素のClass").Click();

注意点として、displayhiddenに設定されている要素はクリックできません。

開いたページ上でJavascriptを実行する

ページの要素を書き換えたり特定のスクリプトをページ上で実行させるときは、ExecuteScriptを使用します。

chrome.ExecuteScript("alert(\"test\")");

ExecuteAsyncScriptは名前の通り非同期にスクリプトを実行する場合に使用します。スクレイピング用途では使用しないと思います。

ヘッドレスモードでChromeを起動する

スクレイピングする際にChromeのウインドウを非表示にするには、ChromeOptionsに起動時の引数を追加してChromeDriverをnewします。

var options = new ChromeOptions();
options.AddArgument("--headless");

var chrome = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), options);

ファイルのダウンロード先を指定する

ファイルのダウンロード先をプログラムのカレントディレクトリにあるdownloadフォルダに設定する例です。

var options = new ChromeOptions();
options.AddUserProfilePreference("download.default_directory", Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\download");
options.AddUserProfilePreference("download.prompt_for_download", "false");
options.AddUserProfilePreference("download.directory_upgrade", "true");

var chrome = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), options);

自動ポップアップブロックを無効にする

var options = new ChromeOptions();
options.AddUserProfilePreference("disable-popup-blocking", "true");

var chrome = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), options);

タブを切り替える

// 最後に開いたタブに切り替える
chrome.SwitchTo().Window(chrome.WindowHandles.Last());

// 最初に開いたタブに切り替える
chrome.SwitchTo().Window(chrome.WindowHandles.First());

Chromeを起動して最初のページを開いた際に以下のようにしておくと楽です。

var rootTab = chrome.CurrentWindowHandle;
...

chrome.SwitchTo().Window(rootTab);