Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
JJUG-2018-Fall-MF2
Search
Takeshi Nakamoto
December 15, 2018
Programming
640
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JJUG-2018-Fall-MF2
Takeshi Nakamoto
December 15, 2018
More Decks by Takeshi Nakamoto
See All by Takeshi Nakamoto
APIへのアクセスが急増して慌てた話 / We Should Know our Application Performance
tksh_n6o
0
810
Other Decks in Programming
See All in Programming
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
450
iOSDC2026登壇資料.pdf
riofujimon
0
150
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
一人だけ、Kiroが静止する日
hideg
0
100
What We Talk About When We Talk About XP
m_seki
2
610
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
490
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
670
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
110
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
120
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
150
Family mrubyの進捗
kishima
1
120
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
1.3k
Featured
See All Featured
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
420
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
980
KATA
mclloyd
PRO
35
15k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
450
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
380
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.3k
エンジニアに許された特別な時間の終わり
watany
108
250k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.7k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
740
A Tale of Four Properties
chriscoyier
163
24k
Transcript
Selenium WebDriverと ヘッドレスChromeを用いた スクレイピング 2018/12/15 JJUG CCC 2018 Fall 中本
武志 1
自己紹介 中本 武志(なかもとたけし) 株式会社マネーフォワード(2016〜) サービス基盤本部アプリケーション部 サーバーサイドエンジニア(Java) 静岡県駿東郡長泉町在住 2
3 熱海 小田原 新横浜 品川 • 通勤は約1時間 • 終電は品川発22:54 •
週1でリモート勤務 ◦ 保育園の送迎 ◦ 家事 三島
内容 1. ヘッドレスChromeの検討を始めた経緯 2. ヘッドレスChromeの使い方 3. アグリゲーションシステムへの組み込み 4. まとめ 開発中プロジェクトの内容となります。
本番環境での運用を始めていないため、遭遇していない問題がある可能性があります。 4
内容 1. ヘッドレスChromeの検討を始めた経緯 2. ヘッドレスChromeの使い方 3. アグリゲーションシステムへの組み込み 4. まとめ 5
マネーフォワードのアグリゲーションシステム • カスタマイズした HtmlUnit を利用したスクレイピング • OkHttp などを利用したAPI連携 • 様々な金融機関サイトに対応
• 毎分4000セッション https://github.com/HtmlUnit/htmlunit 6
対応金融機関 • 銀行、など ・・・ 2279 サイト • カード ・・・ 141
サイト • 証券、投信、FX・貴金属 ・・・ 87 サイト • ポイント ・・・ 41 サイト • 電子マネー・プリペイド ・・・ 37 サイト • 交通(JAL, ANA) ・・・ 12 サイト • 通販(Amazon, 楽天) ・・・ 10 サイト • 携帯 ・・・ 12 サイト • など ・・・ 計 2678 サイト 7
対応金融機関 • API連携でのアグリゲーションも増えている ◦ 仕様が決まっているので、問題なくデータが取得できる ◦ (基本的には)処理速度も速い ◦ ログインパスワードなども預からない •
とはいえ大多数はスクレイピングを行っている ◦ 最近スクレイピングが難しいサイトが増えてきた 8
スクレイピングの課題 例1) MF KESSAI (https://mfkessai.co.jp/) スクレイピングしようとしたらエラーになった 9
スクレイピングの課題 エラー内容 Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot find function resolvedOptions
in object [object DateTimeFormat]. https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/resolvedOptions 2012年ごろ策定されたAPI (?) 10
スクレイピングの課題 エラー内容 Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot find function resolvedOptions
in object [object DateTimeFormat]. https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/resolvedOptions 2012年ごろ策定されたAPI (?) 11 エラーになる箇所と同等の処理を実装して回避
スクレイピングの課題 例2) HtmlUnitの改修 とあるサイトのリニューアル後にスクレイピングできなくなった com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: Assignment to undefined "getHoge"
in strict mode var getHoge = function getHoge() { alert ('foo') } 名前付き関数式でパースに 失敗するパターンが存在した 12
スクレイピングの課題 例) HtmlUnitの改修 暫定対応後に、根本対応を行い、HtmlUnit に報告 13
スクレイピングの課題 • HtmlUnit ではスクレイピングが難しいサイトが増えた • リニューアル等でこれまでできていたスクレイピングが できなくなることが増えた ◦ 解決策を模索するコストが増加 GUIなし(ヘッドレス)で動く本物のブラウザを使ったスクレイピング
を 選択できるようにしておく 14
ブラウザのヘッドレスモード • 2018年7月当時、ヘッドレスモードがあったのは ◦ Google Chrome v68 ◦ Mozilla Firefox
v61 • とりあえず Chrome を使うことにした ◦ ブラウザシェアの多い方に 15
内容 1. ヘッドレスChromeの検討を始めた経緯 2. ヘッドレスChromeの使い方 3. アグリゲーションシステムへの組み込み 4. まとめ 16
ヘッドレスChromeとは Google Chrome v59 から利用できるようになった GUIなしでブラウザを動作させる機能 https://developers.google.com/web/updates/2017/05/nic59 より 17
制御方法 • Chromeをプログラムから操作する手段はいくつか存在する ◦ puppeteer(パペティア) とかが有名 • Java アプリケーションから利用できるものは2つくらい ◦
Chrome DevTools Protocol(CDP) ◦ Selenium/WebDriver 18
制御方法 構成 App App chromedriver WebSocket / CDP HTTP/JSON WebSocket
/ CDP 19 Selenium
Chrome DevTools Protocol Chrome DevTools Protocol(CDP) を使って操作することができる • WebSocket で通信
• JSON 形式のコマンド 20 https://chromedevtools.github.io/devtools-protocol/
Chrome DevTools Protocol { "method": "Page.navigate", "params": { "url": "https://moneyforward.com/"
} } ページ遷移コマンド DevTools Protocol エンドポイントに対して、コマンドを渡して操作する 21
Chrome DevTools Protocol DevTools Protocol のみだとけっこう煩雑 22 - 要素を検索 (DOM.performSearch)
- 検索結果を取得 (DOM.getSearchResults) - 検索結果のボックス情報を取得 (DOM.getBoxModel) - ボックス情報から要素の中心座標を計算 - 中心座標で mousePressed イベントを発火(Input.dispatchMouseEvent) - 中心座標で mouseReleased イベントを発火(Input.dispatchMouseEvent) (注: デバッガ経由での観察結果で、実装の一例です。) ある要素をクリックするために必要な処理
Selenium WebDriver ブラウザ操作の自動化ツール • Chrome も含めた、ブラウザ共通の操作用API • 様々な言語での実装がある 23
Selenium WebDriver App chromedriver ブラウザ固有の WebDriver実装 geckodriver edgedriver etc ...
WebDriver クライアント JSON Wire Protocol (HTTP) 24
chromedriver chrome/chromium 向けの WebDriver 実装 WebDriver 標準API以外にも、いろんなAPIが定義されている https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver • W3C
standard endpoints • Json wire protocol endpoints • Extension commands from other specs • ChromeDriver specific extension commands • Commands of unknown origins CDPコマンドを渡すAPIもある 25
chromedriver 指定可能なオプションやAPIの使い方などは テストコードを見てみるとわかりやすい https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/test/run_py_tests.py 26
chromedriver findElement というコマンドは最終的にJavaScript として実行されていた https://chromium.googlesource.com/chromium/+/trunk/third_party/webdriver/atoms.cc 27
CDP / WebDriver の比較 機能(Chromeの場合) CDP WebDriver 多機能 (DevTools でできることができる)
主にブラウザ操作関連 WebDriver でできることはCDPでもできる 28
CDP / WebDriver の比較 実装(Chromeの場合) CDP WebDriver - ほぼ自前で実装する必要がある (ライブラリはあったが、ライセンスの関係で
見送った) - 学習コストが高そう (puppetterなどのライブラリの実装を読んで 学んだ) - Selenium が提供するクラスが利用可能 - ドキュメントが豊富 - 事例も豊富 29
スクレイピングの要件 アグリゲーションシステムに組み込むための最小限の要件 1. プロキシの利用 2. Cookie の利用 3. ファイルダウンロードの利用 2.
と 3. については問題なく行えた。 4. も動作サンプルは実装できた。 30
ファイルダウンロード HtmlUnit 31 • 同一プロセス内で動作しているため、アプリケーションから直接アクセス可能 ◦ ダウンロード完了イベントなどもわかる ヘッドレスChrome • 別プロセスのため、ファイルシステムを介して取得する必要がある
◦ ダウンロード完了イベントも明示的に取得しないといけない
ファイルダウンロード CDP ダウンロードディレクトリの指定 Page.setDownloadBehavior コマンドで可能 ダウンロード完了判定 ディレクトリのファイル名判定(xxx.crdownload) または リクエスト完了イベントハンドリング(Network.loadingFinished) など
32
ファイルダウンロード WebDriver ダウンロードディレクトリの指定 chrome 起動時のオプションとして設定可能 (prefs.download.default_directory) ダウンロード完了判定 ディレクトリのファイル名判定(xxx.crdownload) または リクエスト完了イベントハンドリング(Network.loadingFinished)
Performance Log を有効にするとCDPと同様のイベントログを取得できる 33
どちらを使うか • CDPのほうがいろいろできるが、実装コストが高い • WebDriver は機能としてはCDPに劣るが、ライブラリの整備な どを考えると使いやすい 実験的な位置づけで、速くリリースに持っていけるWebDriverを採用 34
内容 1. ヘッドレスChromeの検討を始めた経緯 2. ヘッドレスChromeの使い方 3. アグリゲーションシステムへの組み込み 4. まとめ 35
スクレイピング実装 HtmlUnit API WebDriver WebDriver を利用するサービスは、Chrome 及び chromedriver がインストール された特定のサーバーに振り分ける実装を追加
36
構成 アグリゲーション chromedriver 外部サービス systemd 外部サービス 外部サービス server 37
構成 • chromedriver は daemon として起動しておく ◦ スクレイピングセッション毎にchromedriverとchromeが起 動するのは重そうだったので(感想) ◦
同時スクレイピング数を絞った状態でリリースして調整す る予定 38
追加開発した機能 • Selenium 提供の機能でほぼ対応できた • chrome が起動しっぱなしにならないよう確実に閉じるようにし た • 既存の開発スタイルに合わせるため、明示的な待機の実装を
ラップ ◦ 指定時間を過ぎても例外を投げないで戻す ◦ エラー画面になったことを検出できるようにした 39
使ってみた感想1 • スクレイピングできなかったサイトができるようになって 単純にうれしい ◦ スクレイピングできないサイトがなくなった感がある • HtmlUnit と比べてそこまで遅くなった感じはない ◦
ページ遷移時などは速く感じることも ◦ 外部サイトとの通信にかかる時間のほうが大きい ◦ 単純な動作速度よりも、正しいデータを取得できるようになるこ とのほうが重要なため問題ない 40
使ってみた感想2 • けっこうリソースを消費する(CPU/メモリ) ◦ 同時接続数を増やした場合の負荷がどうなるか ◦ 計測した値を元に調整していく • chrome のバージョンアップなどへの追従はどうするか
◦ apt では基本的に最新バージョンしかインストールできない ◦ リポジトリをコピーしてくるなどが必要そう • 既存のライブラリ資産を使えるようにしたい ◦ HtmlUnit 提供のクラスのラッパーなど ◦ 便利メソッドを使えるように改修しないといけない 41
内容 1. ヘッドレスChromeの検討を始めた経緯 2. ヘッドレスChromeの使い方 3. アグリゲーションシステムへの組み込み 4. まとめ 42
まとめ • HtmlUnit 以外のスクレイピングの選択肢を準備したい ◦ そのためにヘッドレス chrome を使う • Chrome
DevTools Protocol は使えたら使いたい ◦ ライブラリ整備ができれば • WebDriver 便利 ◦ サクッと使い始められる ◦ chrome のバージョンアップ等の運用に課題 ◦ リソースは結構消費する模様 • 定量的な評価は今後の課題 43
Thank you! 44
Javaエンジニア募集中 • 扱うデータへ強い責任感をお持ちの方 • この世界に流れるデータを綺麗にしたい!というパッションをお持ちの方 • 大規模トラフィックを捌いてみたい方 • ミドルウェアを使い倒したい方 45