質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

1回答

1766閲覧

既存スクリプトの軽量化(タイムアウト対策)

yukitorte

総合スコア9

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2020/04/15 08:55

度々お世話になります。

https://review-of-my-life.blogspot.com/2018/02/gas-importxml-cron.html を参考に、
2年以上、1時間に1回のペースでwebスクレイピングを行っております。

###現状の問題
動作自体は問題ないのですが、スクレイピング品目(上記サイトで言えば、店舗数)が増えたためか
ここのところタイムアウトが目立つようになってしまいました。
1時間に1回実行している都合、午前の時間帯にタイムアウトが頻発すると
遅い時間の観測にも影響が出る可能性が高く、なんとかしたいのですが……。

APIの実行回数かなんかが限界なのかな……と素人ながら感じておりますが
どのように整頓すればスリムアップできるかが、見当つかない状態です。

setList(*,getListArray(*,5,1,2));は、同形式で現状17まであります。(今後も増えます)
数字の大きな方から記載しているのは、タイムアウトが多発するようになってから行った調整で
最低限、新しい(数字が大きい)観測地点のログは取れるように実行順を前にしよう……という小細工です。

GAS

1var File = SpreadsheetApp.openById('*************************'); 2var baseSheet = File.getSheets()[0]; 3 4function MainFrame() { 5 setTrigger(); 6 //TODO: スプレッドシートの決まった箇所に決まった値を挿入(row,col,rowNum,colNum) 7 setList(5,getListArray(6,5,1,2)); 8 setList(4,getListArray(5,5,1,2)); 9 setList(3,getListArray(4,5,1,2)); 10 setList(2,getListArray(3,5,1,2)); 11 setList(1,getListArray(2,5,1,2)); 12} 13 14//TODO:スプレッドシートに、現在の数を行に追加する 15function setList(sheetNum, ListArray){ 16 var Sheet = File.getSheets()[sheetNum]; 17 Sheet.appendRow(ListArray); 18} 19 20//TODO:指定範囲のセルから、数をリターンする 21function getListArray(row,col,rowNum,colNum){ 22 var array = baseSheet.getRange(row,col,rowNum,colNum).getValues()[0]; 23 var date = new Date(); 24 array.unshift(date) 25 return array; // 取得日時,数をリターンする 26}

###現在の実行記録
直近の実行記録からいくつか記載しておきます。(正常完了したもの)
70.038 秒
73.947 秒
35.345 秒
54.881 秒
63.89 秒
46.868 秒
65.674 秒
60.506 秒
68.692 秒
44.836 秒

###余談
前述のとおり1hごとに観測しているのですが、タイムアウトは圧倒的に日中が多いです。
観測先のサーバー負荷の問題もあるのかな……と思うのですが、このスクリプトを見るに
『IMPORTXMLで観測結果が得られていようがいまいが、実行した瞬間の特定のセルの値を別シートにコピペする』
というように感じます。
実際、ログにタイムスタンプだけがついて観測結果が空欄になることがありますし。

うーん、手動のスクリプト実行も含めて、重さが気になったことはないんですが
Googleも日中が重かったりするんでしょうかねぇ……(・w・`;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

setTrigger と最初のシートにあると推測される IMPORTXML の動作がわからないので、多分改善しないと思いますが、わかる範囲で。

javascript

1const q253851_MainFrame = () => { 2 setTrigger(); 3 const Book = SpreadsheetApp.openById('*************************'); 4 const sheets = Book.getSheets(); 5 const firstSheetValues = sheets[0].getDataRange().getValues(); 6 const config = [[5,6,5,1,2],[4,5,5,1,2],[3,4,5,1,2],[2,3,5,1,2],[1,2,5,1,2],]; 7 config.forEach(e=>{ 8 setList(sheets[e[0]],pickRow(firstSheetValues,...e.slice(1))); 9 }); 10} 11const setList = (sheet, list) => { 12 list.forEach(r=>sheet.appedRow(r)); 13} 14const pickRow = (array, leftTopR, leftTopC, rows, cols) => { 15 const r = leftTopR - 1; 16 const c = leftTopC - 1; 17 return array.slice(r, r + rows).map(e=> [new Date()].concat(e.slice(c,c + cols))); 18}

ここで判明しているコードでほ getSheets や最初のシートへの getValues が複数繰り返されていることが実行時間を長くする要因だと思います。ただ 17 回程度ですと、よくても数秒程度しか改善しないと思います。タイムアウトするということは 70 秒が 6 分のレベルまで延長しているはずで、それはこのコードでは起こっていなさそうです。

投稿2020/04/15 14:08

編集2020/04/15 14:09
papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問