読者です 読者をやめる 読者になる 読者になる

プログラマでありたい

おっさんになっても、プログラマでありつづけたい

ServerLessで、Amazonのほしい物リストから安売り情報を通知するBotを作ったよ

 Serverless Advent Calendar 2016の11日目です。ちょっと趣向を変えて、Serverlessでアプリを構築する場合、こんな感じになったよというのを紹介しようと思います。

Amazonのほしい物リストから商品情報を抜き出して、安売りしていたら通知してくれるBot



 最近の読書はもっぱらKindleさんです。いつでもどこでも、そして保管の場所を取らないというのは素晴らしいですね。このKindleですが、定期/不定期にセールをやっています。問題は頻度と対象が多すぎて、欲しい本を見つけられないという問題です。Kindleのセール情報をまとめているサイトなども多数ありますが、そちらを追うのも大変ですよね。
 そこで、自分が欲しい本だけのセール情報を取得するという方法を考えてみましょう。解決策は簡単で、気になった本は自分の欲しいものリストに追加していき、そこの本が安くなったら通知してくれるBotを作ればよいのです。

Botのアーキテクチャと処理の流れ



 Botは、DynamoDBとLambdaで構成されています。つなぎの部分として、SQSやCloudWatch Eventsを利用しています。
f:id:dkfj:20161212015001p:plain

処理の流れとしては、次のような感じです。

  1. bot宛(@WishlistSales)宛に欲しい物リスト(公開)のURLをつぶやく
  2. CloudWatch Eventsで定期的に起動しているLambdaが、Twitterのmentions_timelineを取得しDynamoDBに登録
  3. DynamoDB StreamsでLambdaを起動し、欲しい物リストのURLから全ページ取得しSQSに登録。※欲しい物リストは、2,500件(250ページ)まで登録出来るので、改ページとアイテム取得を分離するため
  4. SQSのキューを元に登録されているASIN(ISBN)を取得し、DynamoDBに保存
  5. 毎日LambdaからProduct Advertising API(元祖AWS)を利用し、書誌情報を取得し保存
  6. 前日に較べて安くなっていたらTwitterで通知

作ってみて気づいた点



 上記のアプリを、Node.jsで作ってみました。今までもAPI Gateway + Lambdaという組み合わせで使うことが多かったのですが、今回はバッチアプリとしてのNode.jsです。そしたらハマりました。Node.jsは基本的に、非同期処理です。それでバッチを作ると、単純に上から下の流れだと上手く動きません。最初は無理やり同期的に作ってみたのですが、やっぱりしっくりきません。素直にCallbackで処理を書くと、待ち時間に並列で動かすことが出来て成る程という感じでした。ノンブロッキングI/Oの深淵を少し垣間見れたような気がします。やっぱりこの考え方は、身につけないと駄目ですね。
 ちなみにServerLessという点では、特段困る点は少なかったです。強いて挙げれば、lambdaのタイムアウトがあるので1度のバッチサイズを小さくする設計ですね。これは結果的には、処理分割の上で良い影響が出たと思います。lambdaの処理時間は1分⇒5分と延びましたが、もし今後延びたとしても、1つの処理時間は1分以内に保てるような設計を心がけた方が良いと思います。それ以外で言うと、Lambdaに環境変数を保持できるようになったのは大きいです。これだけでも結構開発しやすくなっています。

SQSとStep Functions



 Step Functionsが出たということで、早速使ってみようと検討してみました。しかし、今回の処理でいうとSQSとCloudWatch Eventsで充分でした。理由としては、それぞれの処理の実行のタイミングがバラバラということです。イベント駆動のものもあれば、定期的に実行するというものもあります。そんな訳で、まだStep Fuctionsを使えていません。どっかで使ってみたいですね。
 SQSについては、個人的にはシンプルで非常に使い勝手が良いです。要望としては、SQS⇒Lambdaの直接的なトリガーを作ってくれれば、もっと便利になるのではと思います。まぁ冷静に考えるとLambda同士のつなぎの部分は、Step Functionsでも良いかもしれません。そのうち、再検討します。

生産性



 上記の処理は、実はまだ全部できていません。日々の価格変動と変動を検知して呟く部分が作りかけです。前半分の処理は、新幹線の往復の時間だけでほぼ出来たので、わりと効率的に作れているかなと思います。環境構築の時間がほぼ不要で、処理に専念できるというのは強いですね。記述量も少なく、全部出来たとしてもステップ数は1,000いかないですね。たぶん500くらいなのではという感じです。

感想



 年内中には、ちゃんと公開しようと思います。自分だったらこういう構成にするというのがあれば、コメント頂ければありがたいです。登録しといたら、そのうち安売り情報が届くはずです。
 この程度のアプリであれば、一人で作れて運用負荷も殆どありません。ServerLessというのは目的ではなく、自分がやりたいことを楽に出来る手段だと捉えて、是非いろいろ遊んでみてください。
 最後にちょっとだけ宣伝すると、最近執筆したデータを集める技術に欲しい物リストを取得するウニョウニョも書いています。興味があれば、読んでみてください。

チップス



 あまり技術的な要素は無かったのですが、幾つかチップスも紹介しておきます。

Twitter関係

 Twitterの呟き取得の際、デフォルトでは短縮化されたURLしか取得できません。引数でinclude_entitiesの項目をtrueにしておくと、entities.urls[n].expanded_urlという場所に配置されます。1ツィートで複数あれば、複数項目でてきます。あと、既読を無視する方法が解らなかったので、最終取得Tweetの日時をDynamoDBに保存するようにしています。

  var params = {include_entities: 'true'};
  client.get('statuses/mentions_timeline', params, function(error, tweets, response) {
    if (!error) {
      tweets.forEach(function(tweet) {
          var curDate = new Date(tweet.created_at);
          if (lastDate >= curDate) {
            console.log("new tweet is not exists");
          } else {
            putUrl(tweet.entities.urls[0].expanded_url, tweet.user.screen_name, curDate);
          }
      });
    }
  });
DynamoDB関係

 Node.jsに関しては新旧複数のライブラリが存在します。公式のBluePrintの、dynamo.putItem/getItemとやっているようなのは古い書き方をしています。 公式のチュートリアルを最初に読みましょう
http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/gettingstartedguide/GettingStarted.NodeJs.03.html#GettingStarted.NodeJs.03.01


See Also:
cheerio-httpcliを使って、Amazonのほしい物リスト(Wish List)から商品コード(asin)を抜き出す

参照:
Serverless Advent Calendar 2016

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

非エンジニアでも何とか出来るクローラー/Webスクレイピング術

遅くなりましたが、クローラー/Webスクレイピング Advent Calendar 2016の4日目です。先日、データを集める技術という本を出しました。冒頭の部分は、次のように始まっています。

 2014年8月に「Rubyによるクローラー開発技法」という本を出版しました。書名の通りRubyというプログラム言語を使って、自作のクローラーを作りデータ収集を効率化しようという本です。ニッチなテーマにも関わらず、多くの方に読んで頂けたようです。想定以上の売れ行きで不思議に思って読者層を調べてみると、プログラム書にも関わらずマーケッターやコンサルタントなどITエンジニア以外の読者の方も多かったようです。ITエンジニア以外も読むかもということは、執筆時にある程度念頭には入れていたものの、結果としては想定以上の比率でした。
 そこで、もっと多くの人にデータ収集術を知ってもらう為に本書を執筆しました。前著に較べると、出来るだけ簡単にデータを収集するためのノウハウを中心にしています。ツールを組み合わせてプログラムすることなくデータを集める方法や、Excel・Google スプレッドシートのセル関数などを使う方法、またプログラムする場合もExcelのVBAやGoogle Apps Scriptなど、プログラム環境の構築が不要なもののみを扱っています。その為、プログラマはもとより、プログラマ以外の人でも見よう見まねでクローラー/スクレピングができるのではないでしょうか。

 ここに書いている通り、クローラー/スクレイピングという技術は、エンジニア以外にも有効です。ある意味、エンジニア以上に必要としているかもしれません。一方で、そういう手段すら知らずにいる人が大半だと思います。そこで、出来るだけ多くの人にクローラー/スクレイピングの技術に触れられるようにと考えています。

比較的簡単なスクレイピング方法



 個人的なお勧めの順としては、次のようになっています。なんとExcel + VBAを1番にあげています。

1. Excel + VBA
2. Googleスプレッドシート+セル関数(importxml関数)
3. Googleスプレッドシート+Google Apps Script
4. Import.io

 理由としては、何故かExcelの場合だとプログラムにアレルギーを持っている人も頑張って理解しようとしてくれるのですよね。次のGoogle系の場合、アカウント持っているよという人が比較的多いです。(と言っても、Excel使ったことがあるよという人に較べると、1/10くらいの感覚ですが。)最後のImport.ioが実は一番簡単なのですが、コンソールが英語という所で脱落する人が多いです。

Excel + VBAでスクレイピングの手順



 Excel + VBAでのスクレイピング手順については、こちらのスライドで簡単に説明しています。
www.slideshare.net


 また、データを集める技術で頑張って説明していますが、本質的な部分は、下記の5点くらいです。

  • InternetExplorerクラス
  • HTMLElementCollection
  • getElementByTagName
  • getElementsByClassName
  • getElementById

それぞれの役割は、下記の図のとおりです。
f:id:dkfj:20161205080758p:plain

これを使ってプログラミングしたのが、次のような感じのものです。
f:id:dkfj:20161205080805p:plain

比較的簡単です。頑張れば、プログラミングをやっていない人でも何とかできるかなというレベルです。

クローラー/Webスクレイピングの将来



 個人的には、今後はスクレイピングという技術は、サービス化がもっと進むと思います。今はなくなったkimonolabsやimport.io、あるいはscrapy系のサービスのようなものの普及が進むと思います。ただし、もう一段先があって、サイト運営者自身によるAPIの提供が当たり前になる時代が来るのではないかと思います。その為の、APIのマーケットの整備も進みつつあります。一般人が使う技術としてのクローラー/スクレイピングは、過渡期の技術だと思っています。

感想



 とりとめのない話で発散しましたが、ディスクワークする人にとってはクローラー/スクレイピングという技術があることだけでも知っておいた方が何かと便利です。一昔前に較べると、HTMLも構造化され、それを取るための手段も沢山でてきています。問題のならない範囲で気をつけた上で、是非一度試して貰えればと思います。プログラミングをしたことがない人にとっては、プログラミングの楽しさを知るキッカケにもなると思います。

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

See Also:
「データを集める技術」という本を執筆しました

「データを集める技術」、紙版・Kindle版の発売開始です。

 一部先行発売していましたが、本日「データを集める技術」の発売開始です。紙版だけでなく、Kindle版も同時に発売の模様です。

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

 池袋のジュンク堂書店池袋本店さんには、私の直筆の汚い字のポップを置いています。是非、見に行ってください。またそれ以外にもAWS本・Rubyクローラー本にもそれぞれポップを書いていますので、暇な人は是非みてください。

プレゼントキャンペーン



 宣伝だけしても何なので、connpassでプレゼントキャンペーンも作りました。買うほどでもないなぁという方は、まずは運試しをしてください。connpassの抽選なので、私も手心は加えられません。
connpass.com


データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

データを集める技術 最速で作るスクレイピング&クローラー (Informatics&IDEA)

See Also:
「データを集める技術」という本を執筆しました

「データを集める技術」の販売開始前に修正箇所のお知らせです

 週明けの11/29が、「データを集める技術」の発売日です。その前に残念なお知らせです。Excelによる一発目のサンプルコードであるAmazonのカテゴリーランキングの取得方法が代わりました。

変更点


 サンプルとしてあげている「クラウド の 売れ筋ランキング」のHTMLのタグが変更されていました。1ヶ月ほど前はタイトルのタグの部分は、zg_titleという解りやすいクラス名で表現されていました。今現在だと、a-link-normalという汎用的なタグ名なので、もう少し上のタグからとって子要素の番号で指定する必要があります。その為、下記のようなスマートでない指定が必要です。

    For Each element In objDoc.getElementsByClassName("a-fixed-left-grid-inner")
        'シートに取得したタイトルの書き込み
        Worksheets(1).Cells(row, 1) = row
        Worksheets(1).Cells(row, 2) = element.Children(1).Children(1).innerText
        row = row + 1
    Next element

f:id:dkfj:20161125204820p:plain

今の気持ち


 「Amazon Web Services クラウドネイティブ・アプリケーション開発技法」の発売を待つばかりという段階で、Cognito User Poolが発表されたりLambdaの仕様やAPI Gatewayの管理コンソールのインターフェースがどんどん変わっていく様を見るしかなかった時の気持ちと同じです。いつか必ず起こると思いながら、今起こるのかよと。つまりまぁ、しゃーないです。
 スクレイピング本というものは、変化する前提で割り切るしかないのです。その為、やり方・考え方を伝えるのがメインにしないといけないですねという良い例でした。サンプルソースのページで出来るだけはフォローしていくようにする方針です。

SBクリエイティブ:『データを集める技術』サンプルファイル

データを集める技術 最速で作るスクレイピング&クローラー

データを集める技術 最速で作るスクレイピング&クローラー

「データを集める技術」という本を執筆しました

 Webからデータを集めるというテーマで、「データを集める技術」という本を書きました。中身は、クローラー/スクレイピング本なのですが、それだと内容が「Rubyによるクローラー開発技法」と丸かぶりになってしまうので、本職プログラマでない人でも読めるような内容を目指して書いています。

データを集める技術 最速で作るスクレイピング&クローラー

データを集める技術 最速で作るスクレイピング&クローラー

Excelでデータ収集をする理由


 メインのターゲットは、ITエンジニアです。ただし前述のとおり、プログラマでない人でも何とかなるように目指しています。ということで、メインのデータ収集環境は、ExcelとGoogleスプレッドシートです。何故、Excelを選んだかというと、技術書で10万冊売れるのはExcelだけだから。環境構築の負荷が極小で、かつ普及しているプラットフォームだからです。我々エンジニアからすると、プログラムを実行する環境を構築することは難しくありません。しかし、一般的にはここのハードルは非常に高いのです。そこをどうやって回避するか考えた結果、Excelを選びました。
 Excelはデータ収集のための実行環境として考えると、何気に優れています。少し設定をするだけでVBAというプログラム言語を利用できます。VBAからIEをコントロールできるので、ブラウザのエミュレートをどうするかという問題も不要です。また集めたデータをシートに保存することも可能ですし、グラフや表にまとめて可視化することも出来ます。使える言語がVBScriptのみということに目をつぶれば、中々に優れた環境です。
 Google スプレッドシートも同様の理由で選んでいます。Windows以外という選択肢も増えている中で、Excelの代替となる可能性のあるものの第一候補はGoogle スプレッドシートだと思います。Google スプレッドシートも、JavaScriptベースのGoogle Apps Scriptを使うことで、自由自在にデータ収集ができます。また、スケジュール実行やイベント駆動も出来るので、スクレイピングという枠に留まらず簡易Botの基盤としても有用なのではないでしょうか。冒頭ではExcelを連呼していましたが、実はExcelよりGoogleスプレッドシートの比重が高いです。

データ収集の方針


 私の人生のモットーは、できるだけ楽をしたいです。ということで、データを集めるにしろ出来るだけ楽をしようと考えながら構成しています。具体的にいうと、プログラムをしなくても既にデータをとれる為の手段があるのであれば、それを使う。自分で頑張る必要がある場合でも、ExcelやGoogleスプレッドシートのセル関数だけで済むものがあれば、それだけで完結される。万策尽きた場合のみ、プログラムするという方針です。
 楽をするために、いろいろなサードパーティ製のサービスを使っています。スクレイピングサービスであるImport.ioや、単なる通知ツールにとどまらないIFTTTやmyThings、連携ツールとしてのSlackなどです。

リアルタイム通知



 本書で重視しているのが、データを発見したときのリアルタイム通知です。データを集める目的として、大量のデータを効率的に集めたいというのと、欲しい情報がWeb上にあがったら即座に知りたいというのがあります。前作については前者を重視していましたが、本作については後者となっています。
 理由としては、そういったニーズがかなりありそうだということです。前作のRubyによるクローラー開発技法についても、エンジニア以外の人でも読んでいますという声をだいぶ頂きました。データを集める目的を聞いてみると、マーケティングや広報・企画といったところで、事前調査や反響を知りたいという目的が多かったです。そういった用途の場合、データを集積するということも大事ですが、なるべく早く知りたいという要求も高くなります。その辺りを考えて、モバイルへのリアルタイム通知については多くのページを割いています。
※本を何冊か書いているうちに、エゴサーチの鬼になったので、そのあたりのニーズがよく解るようになったという事情もあります。

まとめ



 上記のような方針で書いているので、今まで書いてきた本と読者層がだいぶ違うようになります。正直なところ、想定している読者層にちゃんと届くのか、またどんな評価になるのか非常にドキドキしています。わりと配本も多いので、少し大きめの本屋であれば置かれるのではないかなと思うので、本屋で見つけたら是非ペラペラとめくってみてください。

 目次は、こんな感じです。

Chapter1 スクレイピングとクローラーで効率的にデータを集めていく
 1-1 データはWeb上に集まる
  Web上に存在するデータの種類
  本書が対象とするデータ
 1-2 効率的にデータを収集するために行うこと
  データ収集の3つのステップ
 1-3 どうすれば自動化できるのか?
  スクレイピングとクローラー
  半自動化プログラムでできること
  完全自動化プログラムでできること
  本書の進め方
 1-4 Webサイトからデータを集める際の注意事項
  収集したデータの取り扱いと著作権
  Webサイトのリソース圧迫と業務妨害
  クローラーとAPI

Chapter2 Excelとブラウザを連携してWebページからデータを収集する
 2-1 Excel VBAでWebからデータを収集する
  Excelでのデータ収集テクニック
  ExcelでVBAが使えるようにする設定
  データを収集するためのプログラム
 2-2 VBAでIEを操作する仕組み
  宣言部分
  VBAの関数の宣言
  IEの操作
 2-3 取得したHTMLから要素を抽出する仕組み
  HTMLの構造
  HTMLから要素を抜き出すプログラム
 2-4 簡単な方法で要素を特定する
  ChromeでXPathを抽出する方法
  FirefoxでXPathの抽出する方法
 2-5 WEBSERVICE関数とFILTERXML関数によるデータ収集
  WEBSERVICE関数によるデータ収集
  FILTERXML関数によるデータ収集

Chapter3 Googleスプレッドシートを利用して自動的にデータを収集する
 3-1 GoogleスプレッドシートとGoogle Apps Scriptを準備する
  Googleスプレッドシートとは
  Google Apps Scriptとは
  関数とクラス
 3-2 ImportXML関数を使ってWebからデータを収集する
  ImportXML関数の概要
  株価データの取得方法
  セルの値を利用した取得方法
 3-3 Google Apps Scriptを利用してデータを収集する
  Google Apps Scriptの使い方
  Google Apps Scriptによるスクレイピング
  Google Apps Scriptの実行
 3-4 指定した時間に定期的にデータを収集する
  Google Apps Scriptのトリガー
  トリガーの設定方法
Chapter4 スクレイピング専用サービスを利用して手軽にWebからデータを収集する
 4-1 import.ioを利用してWebからデータを収集する
  import.ioのサービス概要
  import.ioの利用方法
 4-2 import.ioでスクレイピングを実行する
  import.ioへのサインアップ
  データの自動抽出
  抽出したデータの取得方法
  取得する要素の任意指定
  APIを使ったデータ抽出
 4-3 収集したデータをシート上に保存する
  Googleスプレッドシートとの連携
  Google Apps Scriptとの連携
  Excelとの連携
Chapter5アプリケーションを利用してTwitterからデータを収集する
 5-1 アプリを利用して収集した結果を通知する
  通知を受け取るためのアプリケーション
  IFTTTの概要
  Slackの概要
  myThingsの概要
 5-2 IFTTTを使ってTwitter上でエゴサーチを行う
  IFTTTの会員登録
  モバイルアプリのインストール
  Twitter検索のレシピ作成
 5-3 Slackを利用して定期的にRSS情報を収集する
  Slackの会員登録
  RSSフィードの収集
  モバイルアプリからの利用
 5-4 myThingsを使ってTwitter上でエゴサーチを行う
  会員登録とモバイルアプリのインストール
  Twitter検索の組み合わせの作成
Chapter6 ターゲットを絞り込んで、さまざまなデータを自在に収集する
 6-1 会社・商品に関する情報を収集する
  特定のキーワードを収集する目的
  収集・保存・通知方法
 6-2 Webから特定の「キーワード」に関する情報を収集・蓄積する
  Googleアラートの設定
  IFTTTの設定
  結果の確認
 6-3 Twitterから特定の「キーワード」を含むツイートを収集・蓄積する
  IFTTTの設定
  結果の確認
 6-4 App StoreからiOSアプリのランキングを収集する
  ランキングのRSSフィード
  ランキングの収集
  結果を日付別シートに保存
  指定した時間に毎日実行する
 6-5 Google PlayからAndroidアプリのランキングを取得する
  import.ioを使ったデータ収集
  結果をGoogleスプレッドシートに保存
  日本語ランキングの取得
 6-6 Amazonのカスタマーレビューを収集する
  import.ioを利用した収集方法
  Googleスプレッドシート+ImportXMLによる収集方法
  Google Apps Scriptを利用した収集方法
 6-7 上場企業の時価総額を収集する
  銘柄コード一覧の取得
  株価に関する情報の収集
  時系列で株価データを収集
 6-8 Amazonのセール情報を取得する
  Amazonのほしい物リスト
  ほしい物リストから商品を取得(Excel版)
  ほしい物リストから商品を取得する(Google Apps Script版)
  Amazonの割引率が高い商品を探す
  商品の割引率とポイント還元率の取得(Excel版)
  商品の割引率とポイント還元率の取得(Google Apps Script版)
Chapter7 データを収集した後の見せ方と使い方のヒント
 7-1 クローラー/スクレイピング開発と関連技術
  認証が必要なページからのデータ収集
  大規模なデータ収集
  スクレイピング/クローラー基盤の将来のアーキテクチャ
 7-2 データを可視化して理解しやすくする
  表とグラフ
  Google My Mapsを利用した地図データとの組み合わせ
  その他の地図データの活用
 7-3 集めたデータを組み合わせて分析する
  分析手法
  機械学習サービス「Amazon Machine Learning」

データを集める技術 最速で作るスクレイピング&クローラー

データを集める技術 最速で作るスクレイピング&クローラー

Amazonのほしい物リストをRSS化するAPIを作ってみた

 執筆上の都合でAmazonのほしい物リストをRSS化するAPIを作ってみました。構成的には、次のような形です。

f:id:dkfj:20161024072647p:plain

 下記のようなURLで取得できます。wishlist_idの部分に公開のほしい物リストのIDを指定したら使えると思います。

https://wishlist-api.takuros.net/prod?wishlist_id=3G4653SB32HMZ

※効果計測の意味を兼ねて、アフィリエイトタグを付けています。

構成上のポイント



 ほしい物リストからNode.jsのLambdaでスクレイプして、リスト内のタイトルとURL・登録日を取得しています。また次のページがある場合は、再帰的に取得できるようにしています。出力は、RSS 2.0形式のXMLで出力しています。それをAPI Gatewayを利用してHTTPSからキックできるようにしています。CloudFrontとAWS Certificate Manager, Route53は、独自ドメインで証明書付で使えるようにする為です。
 問題点としては、API Gatewayのタイムアウトが30秒ということです。Lambdaは300秒まで使えるので、10ページくらいのリストであれば問題なく取得できます。API Gatewayの方の制約で、3〜4ページくらいでタイムアウトすることが多いです。ということで、現状は1ページのみ取得となっています。ここについては、取得済みのページをキャッシュする機構等が必要かなと考えています。

API GatewayとLambdaのバージョニング・エイリアス



 仮に公開するとなると、本番/開発環境とかバージョニングとか考えるよなと思って、導入しています。改めて使ってみると、よく出来た仕組みです。一方で、手動で管理するには、ちょっとつらい領域ですね。最初からCLIでスクリプト化する方が良さそうです。もしくはフレームワークの導入ですね。あと、API Gateway+独自ドメイン+SSLについては、現状AWS Certificate Manager(ACM)が使えません。ここの所は、何とかして欲しいですね。

CloudFront+API Gateway



 ここのところが、よく解りません。キャッシュの設定やヘッダーの転送等で上手く動かない部分があります。いろいろ確認する必要を感じました。一方で、API Gatewayの実装って、もともとCloudFrontに関わっているので、CloudFrontを噛ます意味があるのかという所で疑問も出てきますね。

改善点



 スクレイプのタイミングが要調整です。キャッシュがあればキャッシュを返して、そのリクエストベースでキューに溜めてスクレイプしておくくらいの割り切った実装がよさそうです。スクレイプ結果はS3に保存してキャッシュ代わりにするという形です。

感想



 どんなつまらないものでも、公開するという前提で考えるといい勉強になりますね。

データを集める技術

データを集める技術

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

GoogleスプレットシートのImportFeedのキャッシュの話

 GoogleスプレットシートのImportFeedなど、Import系のタブ関数を使っていると2度目はサクッと動きます。それもそのはずで、Google側でキャッシュをしていて、取りに行っていないからです。

ImportFeedのキャッシュの動作


 例えば、下記のように取得し、隣の列にもう一度貼り付けたとしてもすぐに結果が返ってきます。

=IMPORTFEED("https://itunes.apple.com/jp/rss/topgrossingapplications/limit=25/genre=6015/xml","items title","true")

 自分で建てたサーバ上にXMLを配置し、Googleからのアクセスを確認しても2度目以降はアクセスが来ませんでした。問題は、そのキャッシュ時間がどれくらいか解らないこと。また、コントロールする方法が解らないことです。

f:id:dkfj:20161009203936p:plain

※ちなみに新しいURLを発見したと判断したのか、速攻でGoogleBotが来ますね。

ImportFeedのキャッシュ回避策


 取り敢えずの回避策としては、URLを変えてしまうことです。例えば、下記のように引数に意味のない一意の値をいれると、Googleから都度取得するようになります。

https://itunes.apple.com/jp/rss/topgrossingapplications/limit=25/genre=6015/xml?x=20161009201020

まとめ


 これでいいのかという気がしますが、世の中の人はどうしているのでしょうか?正しい方法あれば、教えてください。

追記


定期的に実行させて、サーバー側のアクセスログを見てみました。
12時間前後くらいキャッシュするっぽいような気がします。
テストパターンとか変えて、試してみればもう少し詳しくわかりそうですね。

66.249.77.25 - - [16/Oct/2016:04:24:52 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.79.32 - - [16/Oct/2016:13:58:21 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.79.33 - - [16/Oct/2016:23:52:48 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.79.32 - - [17/Oct/2016:13:52:24 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.71.6 - - [18/Oct/2016:04:33:14 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.77.26 - - [18/Oct/2016:18:00:33 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.79.32 - - [19/Oct/2016:08:19:01 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.79.83 - - [19/Oct/2016:20:43:56 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.79.73 - - [20/Oct/2016:10:38:22 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.75.168 - - [21/Oct/2016:00:41:56 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.65.52 - - [21/Oct/2016:15:12:07 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"
66.249.65.52 - - [22/Oct/2016:06:06:53 +0000] "GET /test.xml HTTP/1.1" 200 358999 "-" "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)"