エラーチェックなど、改良が必要です。
また、トリガーで使用する場合は制限がありますので注意が必要です。
システム要件・完成目標とイメージ
とりあえず今回は適当な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>';
スクレイピングしたいページのコードを見て、タイトル部分を表示しているタグを探します。コードはChromeの場合、右上のメニューから「その他のツール」→「デベロッパーツール」で見れます。
<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行目・77行目:取得したデータからタイトル文字列のみを取り出す
// <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も同じような処理をします。