Rubyのnokogiriとmechanizeの使い分け

  • nokogirirはHTMLドキュメント解析
  • mechanizeは「シンプルログイン」認証突破

「シンプルログイン」の個人的な定義は、「フォームにIDとパスワードを入力してログインボタンをクリックしてマイページへ!」みたいなサイトです。

「え?逆にそれ以外何があるの?」最近よくあるじゃないですか、IDを入れたらパスワード入力フォームが現れたり、ログイン時にページが動的に動くサイト。そういうサイトでもmechanizeで認証とれるかもしれませんが、個人的に私はすぐに諦めます。そういうサイトはすぐにselelniumに移行します。

「すぐ諦めたら、力つかないよ!」確かに一理ありますね。しかし私はスピードとストレスと全体的なコストを比較して、「シンプルログインサイト以外はseleniumに即移行!」とすることにしました。

nokogiriの基本的な使い方

Webページ「https:// ○○○.○○.○○」について

  1. urlを準備
  2. urlのhtmlソースコード取得
  3. nokogiriにコード(String文字列)を放り込む
  4. nokogiriのメソッドを使用して自分の欲しい情報を取得する。
#下記は文字コードの対策はしていません

#ライブライを追記する
require "open-uri"
require "nokogiri"

#nokogiriを準備する
url = "https://○○○.○○.○○"
html = open(url, "r") { |f| f.read }
nokogiri = Nokogiri::HTML(html)

#任意の箇所を抽出する、「nodes」とする
nodes = nokogiri.css("li")

#各要素「node」に同じ処理を施す
nodes.each do |node|
  puts node
  puts node.keys
end

#いろいろ試す
#puts nokogiri.class
#puts nokogiri
#puts nokogiri.to_s.size
#puts nokogiri.methods.sort.count
#puts nokogiri.methods.sort
#puts nokogiri.elements
#puts nokogiri.elements.class
#p nokogiri.elements
#p nokogiri.elements.count
#nokogiri.elements.each do |ele|
#  p ele.keys
#end

mechanizeの基本的な使い方

ログインの工程を言葉にして、それをmechanizeで実行する。

  1. Mechanizeをインスタンス化する。
  2. ログインページのURLを準備する。
  3. ログインページを取得する。
  4. ログインページの中のフォームを捕まえる。
  5. フォームに値をセットする。
  6. サブミットする。
  7. 認証がMechanizeのインスタンスに記憶される。

サンプルで使用したサイトが良くも悪くもいい例でした。勉強になりました。

require "mechanize"

#ログインページを取得する
agent = Mechanize.new
login_url = "https://○○○.○○.○○/signin"
login_page = agent.get(login_url)

#サブミットする
=begin
formsか
form_withか
最初はputsやpやclassで状態を確認するのもよし
https://○○○.○○.○○/signinのソースコードを見て特定できる属性値を探す
=end

login_form = login_page.form_with(id: "login-form")
#p login_form

#field_with()メソッドを使う
login_form.field_with(name: "email").value = "○○○○○@○○○.○○"
login_form.field_with(name: "password").value = "○○○○○○○○○"
logined_page = agent.submit(login_form)
#または「agent.submit(login_form)」のみ

#シンプルログインページならこれでOKです、しかし…。

サンプルサイトだと「Mechanize::UnsupportedSchemeError」が出ました。

あれ?コード・文法は間違っていないと思うけどな。ソースコードを見てみると「フォームのサブミット」ではなく「ボタン」になっている?

調べてみました。

Google検索「mechanize ボタンクリック

【参考】Mechanizeでサイトログインしてスクレイピングするときのアレコレ メモ – Qiita

待てよ?よく見ると「ボタン」ではない。フォーム送信に「aリンク」を使用している。

調べてみました。

Google検索「mechanize リンククリック

【参考】MechanizeとNokogiriでリンク先のページをそれぞれスクレイピングするときのメモ(不規則なページを取得するとき) – Qiita

「link_with」メソッドを使います。使い方は「form_with」と同じです。

logined_page = login_page.link_with(class: "btn btn-primary submit signin user").click

結果…ダメ。また「Mechanize::UnsupportedSchemeError」が出る。

う~ん…コード・文法は間違っていないと思うけどな。

勉強になった

調べてみました。

Google検索「.click link_with mechanize Mechanize::UnsupportedSchemeError

【参考】Ruby – rails スクレイピング Mechanize|teratail

「href」の値が「javascript:;」、そういえばフォームのlogined_pageの「action」の値も「javascript:;」だった。

mechanizeでは「javascript:;」には対応できないようです。よって即、seleniumに移行します。

切り替えが必要

覚えることを少なくしたいからって、mechanizeでどうにかしようと欲が出るとダメだな。
mechanizeでいけたらすごいラクだけど、コーディングで粘るくらいならseleniumにサクッと移行したほうが時間的にも精神的にもいいと思う。

タイトルとURLをコピーしました