Posted at

Mechanizeでサイトログインしてスクレイピングするときのアレコレ メモ

More than 1 year has passed since last update.


デバックで使えるメソッドMechanizeメソッド集


Mechanizeクラスのメソッド

agentのページ遷移の履歴表示

p @agent.history

# [https://sample.com/page1.html, https://sample.com/page1.htm2]


Mechanize::Pageクラスのメソッド

ページのステータスコード表示

p page.code

# "200"


HTTP通信関連の表示

リクエスト、レスポンスヘッダ情報などをロガーで標準出力できる

特に、Mechanize内部で、FormのPOSTで送信されるqueryが見えるので、デバッグで重宝する

require 'logger'

@agent = Mechanize.new
@agent.log = Logger.new $stderr

レスポンスヘッダー取得

pp page.header

{"cache-control"=>"private",
"content-type"=>"text/html; charset=utf-8",
"x-aspnet-version"=>"Secret",
"x-frame-options"=>"sameorigin",
"date"=>"Tue, 05 Apr 2016 07:43:08 GMT",
"content-length"=>"13577",
"set-cookie"=>
"cookie_oishii=1234.0000.4564; expires=Tue, 05-Apr-2016 08:49:09 GMT; path=/, hontoni_oishi=20220.0000; expires=Tue, 05-Apr-2016 08:49:09 GMT; path=/"}

リクエストヘッダの指定

@agent.request_headers = {

'Origin' => 'https://michadameyo.com',
'accept-language' => 'ja,en-US;q=0.8,en;q=0.6,zh-CN;q=0.4,zh;q=0.2',
'Upgrade-Insecure-Requests' => '1',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
}


特定のcookieのvalueの取得・保存・追加

uri = URI.parse("site.com")

# クッキー取得
cookie_str = @agent.cookie_jar.jar["site.com"]["/"]["hoshii_cookie_name"].value
File.write(CAPTCHA_PATH + '/cookie.txt', cookie_str)

# クッキー追加
cookie_str = File.read(CAPTCHA_PATH + '/cookie.txt')
agent.cookie_jar << Mechanize::Cookie.new('hosii_cookie_name', uri.host, {:value => cookie_str, :domain => uri.host, :path=>"/"})


ページ遷移・リソースの取得方法あれこれ


URL指定でページ取得(GET)

top_uri = 'https://www.webpage.com/index.html'

uri = URI.parse(top_uri)
top_page = @agent.get(uri)


URLとPOSTパラメータ指定でページ取得(POST)

uri = 'https://samplesite.com'

response = @agent.post(uri, {
area: 'kumamoto',
region: 'mashiki',
Date: '20160531'
})

doc = Nokogiri::XML.parse(response.body)
pp doc.css('docroot > array')[0].text.split("\n")


クリックでページ遷移する

list_page = top_page.link_with(text: '記事一覧ページ').click

list_page = top_page.link_with(href: '/list?src=ichiran').click


遷移先ページ内のFormを取得して、POSTするパラメータを追加し、送信する

form = page.form_with(name: 'register')

form.action = 'https://minaide_kudasai/login.php'
form.LoginName = 'ID'
form.Passwd = 'PASS'
form.checkbox_with(:name => 'ChkBox').value = '1'

login_page = agent.submit(form)

input fieldの名前によっては、上記の記載ができない場合がある。

その場合はこんな感じで書くと良い。

form = page.forms[0]

form.field_with(name: 'UserId').value = 'ID'
form.field_with(name: 'Password').value = 'PASS'
login_page = agent.submit(form)

puts login_page.body

Formの送信ボタン(submitボタン)にFormパラメータのname,valueが設定されているときは、submitだけでは送信ボタンに付けられたFormパラメータがqueryに追記されないので、submitではなくボタンclickで処理する必要がある。

form = page.forms[0]

button = form.button_with(name: 'login_button')
login_page = @agent.submit(form, button)


mechanizeが保持していないフォームフィールドを自分で追加する

form.add_field!('date', '20160606')


ユーザーエージェントを指定する

@agent = Mechanize.new

@agent.user_agent_alias = 'Windows IE 11'


ページのヒストリーを保持しない

@agent = Mechanize.new

# バックボタンが使える最小個数を保持する
@agent.max_history = 2


画像ファイルなどをダウンロードする

url = base_url + page.search('#LoginWebCaptcha > div.igc_CaptchaImageArea > img').attribute('src').value

@agent.get(url).save_as(CAPTCHA_PATH + "/latest_captcha.gif")


実例集


アパレルECサイトで商品をカートに入れて、買い物を進める感じの一連の操作

require 'mechanize'

require 'pp'

# ログインページ取得
agent = Mechanize.new
agent.max_history = 2
page = agent.get('https://minaide_kudasai/login.php')
page.encoding = 'Shift_JIS'

# ログイン処理
form = page.form_with(name: 'register')
form.action = 'https://minaide_kudasai/dologin.php'
form.LoginName = 'ID'
form.Passwd = 'PASS'
form.checkbox_with(:name => 'ChkBox').value = '1'

login_page = agent.submit(form)
login_page.encoding = 'Shift_JIS'

# トップページへ遷移
top_page = login_page.link_with(text: "トップへ").click

# トップページに表示されたランキング3位の商品ページへ遷移(1-2位は在庫が無かったので3位)
item_page_url = top_page.search('#container > ul:nth-child(2) > li:nth-child(3) > a').attribute('href').value
item_page = top_page.link_with(href: item_page_url).click

# 商品ページ内のカートに入れる
item_id = item_page.search('#container > table tr:nth-child(3) > td:nth-child(3) > div > span').attribute('id').value

cart_in_form = item_page.form_with(name: 'cart_form')
cart_in_form.qId = item_id
cart_in_form.qRetId = item_id
cart_in_form.qMode = 'store'
cart_in_form.qNum = 1

cart_page = agent.submit(cart_in_form)

puts cart_page


気づき


  • Formのパラメータやリクエストヘッダ(特にCookie)をあれこれ手動で設定したくなるが、意外なほどMechanizeは普通のブラウザと同じように振る舞って、情報を集めてくれる。

    本当に追加が必要な情報かどうか、しっかり調べてから、必要なForm、リクエストヘッダのみ追記するようにすること。

    (特に、FormはブラウザとMechanizeのForm 生queryを比較すれば、過不足は明確に分けられるので。)