Yanonoblog!

こつこつと

Mechanizeを用いた外部サイトへのアクセス処理の解説

はじめに

本記事はRailsのMechanizeを使用してスクレイピングする際に、外部サイトのログイン処理を行う方法について解説しています。

社内共有用にしようかと思ったのですが外部向けにダミーコードにして公開します。

Mechanizeとは

今回の実装では、MechanizeというRubyのライブラリを使用しています。

Mechanizeは、Webページの自動操作やスクレイピングを行うためのライブラリで、フォームの送信やリンクのクリックなどの操作をプログラムから行うことができます。

取得というのはHTML要素をMechanizeのメソッドを用いて情報を持たせるということです。

# 1. Mechanizeのインスタンスを初期化
# agentという名前のMechanizeオブジェクトを作成。外部サイトにアクセスするための機能を持っている。
agent = Mechanize.new

# 2. Webページへのアクセス
# agent.get(URL)メソッドを使用して、指定したURL('https://example.com')のページにアクセスしている。
# アクセスした結果(ページのHTML構造)は`page`という変数に格納されている。
page = agent.get('https://example.com')
スクレイピングとは

スクレイピングは、Webページから必要な情報をプログラムを使って自動的に取得する技術のことを指します。

例えば、商品の価格や天気の情報など、Webページに表示されているデータを自動で収集する場合に使用されます。

実装

特定のサイトのログインを行うモジュールの実装例です。

サイトに関する新しい機能やメソッドを追加する場合、実装するモジュールを取り込むことで、すべてのクラスやモジュールで新しい機能を利用することができます。

module FakeSiteAccess
  extend ActiveSupport::Concern

  LOGOUT_URL = 'https://fakesite.com/user/logout'

  private

  def agent
    @agent ||= Mechanize.new
  end

  def login(url, fake_sites_login_id, fake_sites_login_password)
    page = agent.get(url)
    form = page.forms[0]
    form.field_with(name: 'loginID').value = fake_login_id
    form.field_with(name: 'password').value = fake_login_password
    page = agent.submit(form)
    if page.css('.errorText').present?
      message = 'FakeSiteへのログインに失敗しました。ログインIDとパスワードをご確認ください。'
      Rails.logger.error message
      raise message
    end
    sleep 1
    agent.get(url)
  rescue => e
    message = "FakeSiteへのアクセスに失敗しました。(エラー内容:#{e})"
    Rails.logger.error message
    raise message
  end

  def logout
    sleep 1
    agent.get(LOGOUT_URL)
  rescue => e
    message = 'FakeSiteからのログアウトに失敗しました。'
    Rails.logger.error message
    raise message
  end
end

1. モジュールの概要

FakeSiteAccessモジュールは、外部のWebサービスへのログイン・ログアウトを助けるモジュールです。

(ダミーでFakeSiteAccessと命名していますが、通常だとサイト名などで命名するのが好ましいです)

ログイン・ログアウトが必要なサイトにアクセスする際は必須の処理ですね。

このモジュールを実装することで、このサイトのスクレイピング処理を新規実装する際に再利用することができます。

module FakeSiteAccess
  extend ActiveSupport::Concern
  • ActiveSupport::Concernモジュールを拡張して、このモジュールに関連するメソッドやクラスメソッドを簡単に定義できるようにしています。

公式URL: https://api.rubyonrails.org/classes/ActiveSupport/Concern.html


2. 定数の定義

LOGOUT_URL = 'https://fakesite.com/user/logout'
  • WebサービスのログアウトURLを定数として定義しています。
  • サイト側のURLなどは不変な値のため、可読性やメンテナンス性も考慮して定数で管理します。

3. プライベートメソッド

agentメソッド

def agent
  @agent ||= Mechanize.new
end

loginメソッド

  • loginメソッドは、指定されたURL、ログインID、およびパスワードを使用してWebサービスにログインします。
  • ログインに失敗した場合や、何らかのエラーが発生した場合には、エラーメッセージを出力し、例外を発生させます。
  • sleepは、スクレイピングにおいて外部サイトのアクセスする際に間隔を置かないとエラーになるケースがあります。 エラーになる場合はsleepを挟むようにすると解消されることがあります。
# FakeSiteへのログイン処理を行うメソッド
  def login(url, fake_site_login_id, fake_site_login_password)
    # 指定されたURLにアクセスし、そのページの情報をpage変数に格納
    page = agent.get(url)
    # pageから最初のフォームを取得
    form = page.forms[0]
    # フォームのloginIDフィールドにweb_login_idを設定
    form.field_with(name: 'loginID').value = fake_site_login_id
    # フォームのpasswordフィールドにweb_login_passwordを設定
    form.field_with(name: 'password').value = fake_site_login_password
    # 設定された情報でフォームを送信
    page = agent.submit(form)
    # エラーメッセージが存在する場合の処理
    if page.css('.errorText').present?
      # エラーメッセージを定義
      message = 'FakeSiteへのログインに失敗しました。ログインIDとパスワードをご確認ください。'
      # エラーメッセージをログに出力
      Rails.logger.error message
      # エラーメッセージを例外としてスロー
      raise message
    end
    # 1秒待機
    sleep 1
    # 再度指定されたURLにアクセス
    agent.get(url)
  # 例外が発生した場合の処理
  rescue => e
    # エラーメッセージを定義
    message = "FakeSiteへのアクセスに失敗しました。(エラー内容:#{e})"
    # エラーメッセージをログに出力
    Rails.logger.error message
    # エラーメッセージを例外としてスロー
    raise message
  end

logoutメソッド

# FakeSiteからのログアウト処理を行うメソッド
  def logout
    # 1秒待機
    sleep 1
    # 定義されたログアウトURLにアクセス
    agent.get(LOGOUT_URL)
  # 例外が発生した場合の処理
  rescue => e
    # エラーメッセージを定義
    message = 'Webサービスからのログアウトに失敗しました。'
    # エラーメッセージをログに出力
    Rails.logger.error message
    # エラーメッセージを例外としてスロー
    raise message
  end
  • このメソッドは、Webサービスからログアウトします。
  • ログアウトに失敗した場合や、何らかのエラーが発生した場合には、エラーメッセージを出力し、例外を発生させます。

おしまい

コメント

本記事の内容は以上になります!


プログラミングスクールのご紹介 (卒業生より)

お世話になったプログラミングスクールであるRUNTEQです♪

https://runteq.jp/r/ohtFwbjW

こちらのリンクを経由すると1万円引きになります。

RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

https://twitter.com/outputky