Edited at

スクレイピングでBasic認証を扱う。+αフォームからログインする。

More than 3 years have passed since last update.


はじめに

本記事では、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


scraping.rb

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.



ログインする

ここでは、以下のフォームからログインすることを想定しています。


/users/sign_in.html

<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メソッドを使います。


scraping.rb

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の値は実際にログインするフォームで要素の検証をして確認してください。


scraping.rb

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認証」「ログイン」が必要なページをスクレイピングをするために最初にやることです。

これであとは自由にスクレイピングしてください。


完成ソースコード


scraping.rb

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