下町柚子黄昏記 by @yuzutas0

したまち発・ゆずたそ作・試行錯誤の瓦礫の記録

ブラウザ操作の記録・自動実行を補助するツールを作ったけど供養します

この記事は、クローラー/Webスクレイピング&RPA Advent Calendar 2018 Advent Calendar 2018 - Qiitaの6日目の記事です。

何を作ったか

リポジトリyuzutas0/sel2pupとなります。

SeleniumIDEというツールを使うと、ブラウザ操作を記録して .side ファイルを出力します。 そのままでは記録しただけです。実行はできません。 そこで、記録ファイルを.js に変換して、Node.jsでブラウザ操作を自動実行できるようにしました。

ちなみに「Selenium Webdriverを使えばいいじゃん」と思った方はアウトです。 私も最初はそう思いましたが、Seleniumは昔のように動作しなくなっております。 後ほど説明します。

前提

私はデータ基盤のProduct ManagerならびにTech Leadに相当するロールを担っています。 データ基盤とは、企業の持つ多様なデータソースと、多様なデータ活用者を結びつけるための基盤です。

f:id:yuzutas0:20181202174229p:plain

解決したい課題

「広告媒体のデータ収集が高コストだ」という課題です。 一般的にデジタルマーケティングと呼ばれる分野のデータです。

GoogleTwitterFacebookなどの有名な広告媒体にはWebAPIが整備されています。 どのキャンペーンやクリエイティブに、どのくらいのコストを消費して、どのくらいのユーザーが見て、どのくらいのユーザーがクリックしたのか。 そういった効果データをWebAPI経由で参照することができます。 そのため、他データと繋げて高度なデータ分析をしたり、媒体横断の定型レポートを自動生成することができます。

しかしマイナーなメディアではWebAPIが提供されていません。 例えば、学生起業家がWordPressで運営しているファッションメディアを想像してください。 そういうマイナーでニッチなメディアには独自の強みがあります。 特定分野に興味のある熱狂的なユーザーがついているのです。 インプレッション(広告表示)の絶対数は少ないですが、コンバージョン(登録や購買)率が高くなる傾向にあります。

費用対効果が極めて高い、魅力的な広告媒体なのですが、いかんせんシステム面が貧弱です。 広告の効果データを自動収集したくてもWebAPIが提供されていません。

一般的な解決策

オペレーションスタッフが、広告コンソール画面を開き、効果レポートのCSVファイルをダウンロードする。 要するに「手動対応」が一般的な解決策とされています。 単純作業かつスケールメリットが効くので、大手広告代理店の場合は、オフショアで相対的に単価の安い国に発注します。 この方法のメリットは作業パフォーマンスが安定することです。

一方でデメリットはデータ活用のパイプライン処理に乗せにくいことです。 効果レポートを出して終わりではありません。 広告の効果データをインプットにして、次の意思決定や機械学習に繋がるはずです。

もう1つ言われる解決策が、スクレイピングによる自動データ収集です。 人間が手作業を行う代わりに、システムが自動的にブラウザを動かして、CSVファイルをダウンロードして、指定のフォルダにファイルを置きます。 少しプログラミングをかじったことのあるマーケッターなら1度は試したことがあるでしょう。 データ活用のパイプライン処理に乗せることができれば、意思決定や機械学習における可能性が広がります。

しかしこの方法には致命的な欠陥があります。 システムの保守が尋常じゃなく大変なのです。 毎日のようにスクリプトが壊れます。 媒体追加も必要になります。 「マーケッターが新規媒体を追加したいスピード」は「エンジニアの対応速度」を常に上回ります。 大手広告代理店を除いて(筆者の観測範囲では)独自で2年以上運用が続いている実績を聞いたことがありません。 1度やったことがある人なら分かると思います。 長期保守は極めて困難です。

打ち手

そこで私が考えたのは手動・自動のハイブリッド案でした。 基本的にはシステムで自動化する。 だけど保守が必要になる。 その保守をオフショア部隊が担う。 という構想です。

もしくはマーケッター自身がエンハンスできるようにする。 それだけで十分だとも思いました。 いわばRPAの保守工程の一部を非エンジニアが担う世界です。

技術的な課題

ブラウザの動作を記録・実行する方法はいくつかあります。

Selenium

昔ながらのエンジニアがよく知っているのは「Selenium」ではないでしょうか。 主に「SeleniumIDE」(記録)と「Selenium WebDriver」(実行)に分かれています。 数年前ならボタンをポチポチやっていれば自動でそれっぽいコードを生成できました。

しかしなんと、こちら主要ブラウザの仕様変更に伴って、記録→実行ができなくなりました。 詳しく説明します。

Selenium WebDriverはJavaをはじめとしたプログラミング言語で使うライブラリです。 昔のSeleniumIDEは .java などのファイルを出力できました。 出力したJavaソースコード上でSelenium WebDriverを使う形になります。

しかしブラウザの仕様変更に伴ってSeleniumIDEが昔と変わってしまいました。 唯一出力できる .side ファイルの実態はjsonです。要するに設定ファイルです。 Selenium WebDriverは設定ファイルを読み込んで実行するわけではありません。

そのため(2018年12月現時点では)SeleniumIDEとSelenium WebDriverの連携ができなくなったのです。

これまでのツールとの互換性や、Selenium WebDriverなどの形式へのエクスポート機能も現状では存在しません。

Webブラウザ自動化ツール「Selenium IDE」の今までとこれから|Qbook+ https://www.valtes.co.jp/qbookplus/509

公式リポジトリにもWIPの記載があります。

This project is a work in progress, a complete rewrite of the old Selenium IDE.

https://github.com/SeleniumHQ/selenium-ide/blob/v3.5.0-alpha.0/README.md

Selenium の現状については『エキスパートが教えるSelenium最前線』の共著者である @poohsunny さんに教えていただきました。 この場を借りてお礼申し上げます。誠にありがとうございます。

エキスパートが教えるSelenium最前線 (CodeZine Digital First)

エキスパートが教えるSelenium最前線 (CodeZine Digital First)

Puppeteer

Seleniumと並び、特に最近有名なのが「Puppeteer」です。 Google Chrome の公式リポジトリで開発されています。 Node.jsやPythonと相性が良く、サーバレス系ソリューション(AWS Lambda や Google Cloud Functions)をはじめとして、モダンな環境で使いやすいという声が目立ちます。

Puppeteer自体はブラウザでの処理実行を責務としています。 代わりにGUIでブラウザを記録するためのツールとして「Puppeteer Recorder」や「segmentio/daydream」が公開されています。

しかし、これらのツールは、今のところ機能面で使い物になりません。 (2018年秋現時点では)クリック処理さえまともに記録できません。

実装

ということで、最低限のレコーディングができるツールとして「SeleniumIDE」を採用しました。 jsonファイルの出力まではやってくれます。 そのjsonファイルの設定内容をもとにして「Selenium WebDriver」もしくは「Puppeteer」向けのスクリプトを生成すればOKです。

両方とも作って実験したのですが、最終的にはPuppeteerを採用することにしました。 まぁぶっちゃけSelenium WebDriverでも特に問題なかったのですが、最後はノリです。

SeleniumIDEでブラウザ動作を記録する。 readmeに沿ってコマンドをぽちぽちと押していく。 必要に応じて設定ファイルを書き換える。 これでPuppeteerのスクリプトを出力します。

なお、機能スコープは最小限に抑えています。

  • 指定したURLにジャンプする
  • ボタンをクリックする
  • フォームにテキストを入力する
  • 新しいブラウザタブに遷移する
  • 元のブラウザタブに遷移する

これらの単純な処理だけが変換対象です。 入り組んだ動作を自動化するにはがっつりプログラミングしないといけません。

テスト

いくつかの広告媒体を対象にしてテスト実施しました。 ある日の手動作業をレコーディングして、スクリプトに変換して、次の日からRPA的に自動実行する。 感覚値ですが7割くらいの精度で動作しました。

SPA(シングルページアプリケーション)でぬるぬる動く系のダッシュボードだと、レコーディングが上手くいかずに多少のコード修正は必要になりました。 そこはさすがに仕方ないですね。 許容範囲かなと思います。

また、このツールを作ったときに同僚のエンジニアに指摘されたのが「独自に作るなら公式にプルリク出せや」というツッコミでした。 そりゃそうだ。 SeleniumやPuppeteerのコミュニティでのやりとりを見ると、方針を決めるためのディスカッションだとか、既存のシステムの構造だとか、なんだか色々と読み解かないといけなそうで、ちょっと尻込みしてしまいました。

なので、このツールは「公式が出るまでの繋ぎの位置づけ」としました!

供養する理由

公式ツールを使えるようになったわけではありません。 ツール自体の良し悪しでもありません。

ツールを使うための目的がなくなってしまったのです。 「デジタルマーケティングのデータ収集」という業務を「手動・自動のハイブリッドRPAで運用する」という打ち手。 あまり上手くいきませんでした。 主に2点の理由があります。

1点目は個々のプレイヤーの問題です。 データ収集RPAを非エンジニアが保守できる世界を目指して、このツールを作りました。 しかし、多くのマーケッターは既存業務で手一杯のため、保守を自分で担うモチベーションを持つわけではありません。 同様に、エンジニアはシステム構築ができても、導入支援を丁寧に行うことが得意ではありません。 つまり「現場が受け入れる土壌」を育てる必要があったのです。

2点目は全体の経営リスクの問題です。 中途半端に内製部隊が作業するよりも、広告代理店に全部お願いしたほうが(短期的には)ROIが最大化できるのです。 サービスを200個くらい持っていて集客予算をガンガン投下している大企業なら、RPA+オフショアの導入でスケールメリットを得ることができます。 そうでない場合は自前で運用するだけの量的メリットはありません。 かといって、そういう大企業は既に広告代理店のお得意様になっています。 わざわざリスクを冒さずとも、既存のやり方を続けておけば無難でしょう。 代理店に莫大な手数料を支払っているとはいえ、安定的に運用できるからです。 つまり「マーケティング内製化」というトップダウンの経営方針なしには実現できないのです。

どちらも突破できる壁だとは思います。 簡単ではないでしょうが、やりがいのあるテーマです。 が、世の中には他にも面白いことは山ほどあります。 ということで、色々と考えたのですが、まぁ、供養します。

データ基盤は色々と大変だ。 めでたしめでたし。

追記

記事のパブリッシュ直前で、少し風向きが変わりました。

ブログ「酒と泪とRubyとRailsと」の運営者である@zyunnosukeさんとお茶したときのことです。 「個人開発で価格比較サイトを2年以上運営している」「技術要素としてはPuppeteerを活用している」という旨の話を伺いました。 ちなみにこの話は「個人開発の事例集」に寄稿していただく予定です。

そしてですね、私は思い至りました。 このツールはデータ基盤のためだけじゃない。 個人開発やアグリゲーションサービスで使えるのではないか。 アフィリエイトサイトでも強いところは商品の口コミを自動収集していたりしますよね。 そういう用途だとまだまだ可能性があるんじゃないかな。

ということで、私の中では供養したつもりだけど、機会があったらがんがん使っていくぞ!