#はじめに
本記事では、basic認証を使用しているページをスクレイピングするときにbasic認証を扱う方法を示しています。
さらに、ログインフォームからログインしなければページにアクセスできない場合を想定して、テキストフィールドを扱う方法も示しています。
#流れ
・add_authでBasic認証を扱う
・ログインフォーム内のテキストに文字を入力し、ログインボタンを押す
・トップページのHTMLを取得する
#Basic認証を扱う
##add_auth
mechanizeでbasic認証を扱うには、add_auth()を使用します。
第一引数→basic認証の対象のURL
第二引数→basic認証に使用するid
第三引数→basic認証に使用するpassword
以下のようにしてbasic認証を使ったページにアクセスします。
なお、ここではbasic認証に使用するidとpasswordを以下のように定義します。
id → basic_id
password → basic_password
require 'mechanize'
url = 'http://hogehoge.com'
basic_id = 'hoge'
basic_password = 'basichogehoge'
agent = Mechanize.new
agent.add_auth(url, basic_id, basic_password)
#basic認証後にログインする必要なければ、このままページの情報を取得します。
page = agent.get(url)
##auth()とbasic_auth()
これは使用すると以下のようなエラーがでます。ここでは#authと#basic_authの使用は、セキュリティ上の脆弱性に起因して推奨されません。
と言われています。これは、authとbasic_authがbasic認証を使用しているurlを指定しないために、ユーザー名とパスワードを必要としない場合でも送ってしまい、不具合を起こすためらしいです。
At test6_scraping.rb line 11
Use of #auth and #basic_auth are deprecated due to a security vulnerability.
You have supplied default authentication credentials that apply to ANY SERVER.
Your username and password can be retrieved by ANY SERVER using Basic
authentication.
THIS EXPOSES YOUR USERNAME AND PASSWORD TO DISCLOSURE WITHOUT YOUR KNOWLEDGE.
Use add_auth to set authentication credentials that will only be delivered
only to a particular server you specify.
#ログインする
ここでは、以下のフォームからログインすることを想定しています。
<form action="/users/sign_in" method="post">
<h1>ログイン</h1>
<input type="email" name="email" placeholder="メールアドレスを入力">
<input type="password" name="password" placeholder="パスワードを入力">
<input type="submit" value="ログイン" name="login">
</form>
まずログイン画面のhtml情報を取得するために、ログイン画面のurlを引数にgetメソッドを使います。
require 'mechanize'
url = 'http://hogehoge.com'
basic_id = 'hoge'
basic_password = 'basichogehoge'
agent = Mechanize.new
agent.add_auth(url, basic_id, basic_password)
#以下追加文
agent.get(url + '/users/sign_in') do |page|
#このブロック内でpage変数を使用する
end
次に、今取得したログイン画面のhtml情報が格納された変数pageに対して、フォームの値にログインするために必要な情報を入力するための作業をします。
作業内容としては、
1.form要素を取得する
2.form内のテキストフィールドにログイン情報(今回はlogin_emailとlogin_password)を入力する
3.form内の送信ボタン(ログインボタン)をクリックする。
field_withメソッドの引数のactionとnameの値は実際にログインするフォームで要素の検証をして確認してください。
require 'mechanize'
url = 'http://hogehoge.com'
basic_id = 'hoge'
basic_password = 'basichogehoge'
#新しく定義
login_email = 'hoge@gmail.com'
login_password = 'loginhogehoge'
agent = Mechanize.new
agent.add_auth(url, basic_id, basic_password)
agent.get(url + '/users/sign_in') do |page|
# 作業1
page.form_with(action: '/users/sign_in') do |form|
# 作業2
form.field_with(name: 'email').value = login_email
form.field_with(name: 'password').value = login_password
# 作業3
form.click_button
end
end
作業1について
ログインページのhtml情報が格納されているpage
に対して、form_with
メソッドを使用することでフォームを取得します。今回引数でaction: '/users/sign_in'
を指定することで、action属性に'/users/sign_in'を持つフォームを特定しています。これは実際に取得したいフォームを要素の検証で確認してください。
作業2について
作業1で取得したformに対して、field_withメソッドを使用することで任意のテキストフィールドを取得しています。今回引数にname: 'email'
とname: 'password'
とすることで、それぞれname属性が'email'、'password'のテキストフィールド二つを取得しています。
valueメソッドと*=
(代入)*を使用することでテキストフィールドの値にこちらから任意の値を入力しています。
作業3について
作業1で取得したform内にあるボタンをクリックしてテキストフィールド内に入力したものを送信します。
以上が、「basic認証」「ログイン」が必要なページをスクレイピングをするために最初にやることです。
これであとは自由にスクレイピングしてください。
#完成ソースコード
require 'mechanize'
url = 'http://hogehoge.com'
basic_id = 'hoge'
basic_password = 'basichogehoge'
login_email = 'hoge@gmail.com'
login_password = 'loginhogehoge'
agent = Mechanize.new
agent.add_auth(url, basic_id, basic_password)
agent.get(url + '/users/sign_in') do |page|
page.form_with(action: '/users/sign_in') do |form|
form.field_with(name: 'email').value = login_email
form.field_with(name: 'password').value = login_password
form.click_button
end
end