エラーチェックなど、改良が必要です。
また、トリガーで使用する場合は制限がありますので注意が必要です。
システム要件・完成目標とイメージ
とりあえず今回は適当なyahoo!オークションのこんな感じのページから、「リンクタイトル」「値段」「url」の3つのデータを取り出し一覧にするという簡単なものとします。スクレイピングをするにあたり、「Parser」というライブラリを使用します。
「Parser」の他にも色々なライブラリがありますので、探してみると面白いかもしれません。
スプレッドシートの準備
まずはスプレッドシートを用意します。 イメージはこんな感じで。ここはas you likeです。 メニューの「ツール」からスクリプトエディタを起動します。まだインストールしてないよって人はインストールから。
【GAS】GAS(Google App Script)の導入手順
Google App Script 導入手順
Parserライブラリの導入
Parserライブラリを使用するため、プロジェクトに導入していきます。左側の「ライブラリ」から+ボタンを押して追加します。 スクリプトIDに「1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw」を入力し、「検索」。 バージョンは「8」で、「追加」。
これでParserを使用する準備が出来ました。
ソースコード
// ----------------------------------------------------------------------------- // スクレイピングサンプル. // ----------------------------------------------------------------------------- // 出力先のスプレッドシートID. var SheetID = "スプレッドシートのIDを指定"; // 定数. var DataStartY = 2; var DataTitleX = 1; var DataPriceX = 2; var DataURLX = 3; // ----------------------------------------------------------------------------- // myFunction. // 名前はどうだっていい. // ----------------------------------------------------------------------------- function myFunction() { var outSheet = SpreadsheetApp.openById(SheetID).getSheetByName('log'); // リセット処理. outSheet.getRange( 2,1, outSheet.getLastRow() ).clearContent(); var options = {muteHttpExceptions : true}; var response = UrlFetchApp.fetch( 'ここにスクレイピング先のURLを指定', options ); // タイトルを取得. var fromText = '<h3 class="Product__title">'; var toText = '</h3>'; var dataList = Parser.data(response.getContentText()).from(fromText).to(toText).iterate(); // <a>タグを外す処理. for(var i = 0; i < dataList.length; i++ ) { dataList[i] = getTitle( dataList[i] ); } outputData( outSheet, dataList, DataTitleX ); // urlを取得. dataList.splice(0); dataList = Parser.data(response.getContentText()).from(fromText).to(toText).iterate(); // urlを取り出す処理. for(var i = 0; i < dataList.length; i++ ) { dataList[i] = getURL( dataList[i] ); } outputData( outSheet, dataList, DataURLX ); // 値段を取得. fromText = '<span class="Product__priceValue u-textRed">'; toText = '</span>'; dataList.splice(0); dataList = Parser.data(response.getContentText()).from(fromText).to(toText).iterate(); outputData( outSheet, dataList, DataPriceX ); } // ----------------------------------------------------------------------------- // outputData. // 指定スプレッドシートにスクレイピング結果を出力する. // ----------------------------------------------------------------------------- function outputData( outSheet, dataArray, indexX ) { for(var i = 0; i < dataArray.length; i++ ) { outSheet.getRange(i + DataStartY, indexX).setValue( dataArray[i] ); } } // ----------------------------------------------------------------------------- // getTitle. // 指定stringから<a>ここを抜き出す</a>. // 失敗したら"". // ----------------------------------------------------------------------------- function getTitle( str ) { var tmp = str.match(/>.*?</gi); if ( tmp === null ) { return ""; } return tmp[0].substr(1, tmp[0].length-2); } // ----------------------------------------------------------------------------- // getURL. // 指定stringからhref="ここを抜き出す". // 失敗したら"". // ----------------------------------------------------------------------------- function getURL( str ) { var tmp = str.match(/href=".*?"/gi); if ( tmp === null ) { return ""; } return tmp[0].substr(6, tmp[0].length-7); }
実行結果
解説
6行目:スプレッドシートID
// 出力先のスプレッドシートID. var SheetID = "スプレッドシートのIDを指定";スプレッドシートのIDとは、スプレッドシートを開いた時のURLの「d/~/」「~」部分です。
20行目:シート名
var outSheet = SpreadsheetApp.openById(SheetID).getSheetByName('log');「log」の部分は各々のシート名に合わせてください。
32行目:タイトルを取得するためのタグを設定
var fromText = '<h3 class="Product__title">'; var toText = '</h3>';スクレイピングしたいページのコードを見て、タイトル部分を表示しているタグを探します。
<h3 class="Product__title"> <a class="Product__titleLink" href="https://page.auctions.yahoo.co.jp/jp/auction/k521422870" rel="noopener" target="_blank" data-ylk="rsec:aal;slk:tc;pos:1;atax:0;arbn:;catid:2084048018;cid:k521422870;etc:p=2222,etm=1610806119,stm=1610201319,w=2,wtm=1610424400,we=1,wo=1,vsc=-1.2394298261409065;sid:ekalder_xf;st:1610201319;end:1610806119;op:;grat:100.0;ppstr:;seltyp:2;best:" title="ローズマリー マリンブルー 5号 スリット鉢" data-rapid_p="155">ローズマリー マリンブルー 5号 スリット鉢</a> </h3>例の場合、<h3 class="Product__title">から</h3>がすべての商品名のタグで共通で使用されることがわかります。
これを指定すると、<a>~</a>がごっそり取得されますが、気にせず進めます。
35行目:
var dataList = Parser.data(response.getContentText()).from(fromText).to(toText).iterate();システムに丸投げです。ありがたや。
配列形式で返ってきます。
38行目・78行目:取得したデータからタイトル文字列のみを取り出す
// <a>タグを外す処理. for(var i = 0; i < dataList.length; i++ ) { dataList[i] = getTitle( dataList[i] ); } ~~~~ function getTitle( str ) { var tmp = str.match(/>.*?</gi); if ( tmp === null ) { return ""; } return tmp[0].substr(1, tmp[0].length-2); }getTitle()内でmatch()を使った文字列取得処理をしています。
ここの処理は色々と方法があるので、これが一番、という事ではありません。
今回はこの方法でやってみた。というだけの事です。
41行目・66行目:スプレッドシートに入力する
outputData( outSheet, dataList, DataTitleX ); ~~~~ function outputData( outSheet, dataArray, indexX ) { for(var i = 0; i < dataArray.length; i++ ) { outSheet.getRange(i + DataStartY, indexX).setValue( dataArray[i] ); } }outputData()では指定列にデータを入力する処理を書いています。
適当なので、参考程度に。
以下、値段、urlも同じような処理をします。