Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JJUG-2018-Fall-MF2
Search
Takeshi Nakamoto
December 15, 2018
Programming
0
520
JJUG-2018-Fall-MF2
Takeshi Nakamoto
December 15, 2018
Tweet
Share
More Decks by Takeshi Nakamoto
See All by Takeshi Nakamoto
APIへのアクセスが急増して慌てた話 / We Should Know our Application Performance
tksh_n6o
0
730
Other Decks in Programming
See All in Programming
ECMAScript、Web標準の型はどう管理されているか / How ECMAScript and Web standards types are maintained
petamoriken
3
390
メモリ最適化を究める!iOSアプリ開発における5つの重要なポイント
yhirakawa333
0
400
デザインシステムとコンポーネント指向によるフロントエンド開発プロセスの革新 / Innovation in Frontend Development Processes through Design Systems and Component-Oriented Architecture
nrslib
8
5.3k
GraphQL あるいは React における自律的なデータ取得について
quramy
11
2.8k
実践 Advanced CallKit 〜快適な通話の実現に向けて〜
mot_techtalk
3
120
[DroidKaigi 2024] Android ViewからJetpack Composeへ 〜Jetpack Compose移行のすゝめ〜 / From Android View to Jetpack Compose: A Guide to Migration
syarihu
1
240
ドメイン駆動設計を実践するために必要なもの
bikisuke
3
320
僕が思い描くTypeScriptの未来を勝手に先取りする
yukukotani
9
2.3k
いまから追い上げる、Jetpack Compose トレーニング
nyafunta9858
0
240
Rustではじめる負荷試験
skanehira
5
1.2k
いつか使える ObjectSpace / Maybe useful ObjectSpace
euglena1215
2
130
長期運用プロダクトの開発速度を維持し続けるためのリファクタリング実践例
wataruss
8
2.7k
Featured
See All Featured
Being A Developer After 40
akosma
83
580k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
29
2.6k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
109
6.9k
It's Worth the Effort
3n
182
27k
From Idea to $5000 a Month in 5 Months
shpigford
379
46k
StorybookのUI Testing Handbookを読んだ
zakiyama
26
5k
Thoughts on Productivity
jonyablonski
66
4.2k
Bash Introduction
62gerente
608
210k
How to train your dragon (web standard)
notwaldorf
85
5.6k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Building Adaptive Systems
keathley
36
2.1k
Writing Fast Ruby
sferik
623
60k
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