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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Javadoc

Javadocは、Java言語で記述されたクラスライブラリ、及びアプリケーションについてのパッケージ・クラス・メソッドのHTML形式のAPI仕様書のことを指します。ドキュメント更新の漏れを減らすことができ、最新の状態を把握することが可能になります。

Google Apps Script

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

Q&A

解決済

1回答

1428閲覧

GASのスクレイピングを失敗したときの処理

basara

総合スコア7

Javadoc

Javadocは、Java言語で記述されたクラスライブラリ、及びアプリケーションについてのパッケージ・クラス・メソッドのHTML形式のAPI仕様書のことを指します。ドキュメント更新の漏れを減らすことができ、最新の状態を把握することが可能になります。

Google Apps Script

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

0グッド

1クリップ

投稿2022/04/08 09:04

スプレッドシートにURLを記述すると<title>タグ、デスクリプション、カノニカルを取得する下記のコードをGASで作成したのですが、
途中で存在しないURLが入っているとその列の<title>タグ等の入力をスキップし、そのままその後のURLの値が入ってしまうため最終的に1列ズレてしまいます。
存在しないURLまたは間違っているURLを入力した際にスキップではなくその列に「エラー」等の文字列を入力し、ズレが起きないようにしたいのですが
もしその方法がわかる方がいらっしゃいましたらご助力お願いしたいです。よろしくお願いいたします。

Google

1function TDextract(){ 2 const sheet = SpreadsheetApp.getActiveSheet(), 3 startRow = 2, 4 startCol = 6, 5 URLListRow = startRow - 1, 6 7 metaInfo = [ 8 { 9 outName:'desc', 10 name:'name', 11 prop:'description', 12 } 13 ] 14 15 16 /* 17 ======================================== 18 以下 script 19 ======================================== 20 */ 21 22 // clear cell 23 for (let i = startRow; i <= sheet.getLastColumn(); i++){ 24 const dataRange = sheet.getRange(startCol,i,sheet.getLastRow()); 25 dataRange.clearContent(); 26 } 27 28 // create url data 29 const urlData = sheet.getRange(startCol,URLListRow,sheet.getLastRow() - 1).getValues(); 30 let ary = ''; 31 for (var a = 0; a<urlData.length;a++){ 32 if(urlData[a][0]){ 33 ary = ary + String(urlData[a][0]) + ',' 34 } 35 } 36 ary = ary.split(','); 37 ary.pop(); 38 39 40 // header option 41 const options = { 42 method: "GET", 43 "muteHttpExceptions" : true, 44 "validateHttpsCertificates" : false, 45 "followRedirects" : false 46 } 47 let result = []; 48 49 // get html data 50 for(var i = 0; i < ary.length; i++){ 51  try { 52   let obj = Object.assign({}); 53   let r = Object.assign({}); 54   let resultURL = ary[i]; 55   const res = UrlFetchApp.fetch(resultURL,options); 56 const content = res.getContentText() 57 const $ = Cheerio.load(content); 58 obj.title = $('title').text(); 59 metaInfo.forEach((v)=>{ 60 const reg = new RegExp(v.prop,'g'); 61 if(content.match(reg)){ 62 obj[v.outName] = $(`meta[${v.name}="${v.prop}"]`).attr("content"); 63 }else{ 64 obj[v.outName] = false; 65 } 66 }) 67 obj.canonical = $('link[rel="canonical"]').attr('href'); 68 69 r.props = Object.assign({},obj); 70 71 result.push(r); 72 73 obj = null; 74 r = null; 75 Utilities.sleep(1000); 76 } catch(e) { 77 console.log('Error:'+e); 78 } 79 } 80 81 // draw cell 82 result.forEach((d,r)=>{ 83 Object.keys(d.props).forEach((k,i)=>{ 84 const row = startCol + r; 85 const col = startRow + i; 86 sheet.getRange(row, col).setValue(d.props[k]); 87 }) 88 }) 89}

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

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

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

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

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

guest

回答1

0

ベストアンサー

ズレる原因

・URLの内容を正常に読み取れた時は

result.push(r);

で、データが追加されます。

・一方、URLが存在しない場合など、例外が発生したときは catch節にジャンプして、エラー内容を表示した後、次のループに移行します。
このとき(=catch節にジャンプしたとき)、resultに何も追加していないから、ズレてしまいます

解決策

正常時だけでなく、例外発生時にも、何らかのデータをresultに追加するようにしてはいかがでしょうか。

cheerioのドキュメント@GitHubを流し読みしたところ、
load関数にHTMLをそのまま突っ込めば、突っ込んだHTMLをパースしてくれるらしいということがわかります。
<title>タグだけ入れて試したら、タイトルとして認識してくれました)

修正後のコード

js

1() 2 // get html data 3 for (var i = 0; i < ary.length; i++) { 4 5 let obj = Object.assign({}); 6 let r = Object.assign({}); 7 let resultURL = ary[i]; 8 let content; 9 try { 10 const res = UrlFetchApp.fetch(resultURL, options); 11 content = res.getContentText(); 12 } catch (e) { 13 console.log(`Error:${e}`); 14 content = "<title>エラー</title>" 15 } 16 17 const $ = Cheerio.load(content); 18 obj.title = $('title').text(); 19 metaInfo.forEach((v) => { 20 const reg = new RegExp(v.prop, 'g'); 21 if (content.match(reg)) { 22 obj[v.outName] = $(`meta[${v.name}="${v.prop}"]`).attr("content"); 23 } else { 24 obj[v.outName] = false; 25 } 26 }) 27 obj.canonical = $('link[rel="canonical"]').attr('href'); 28 29 r.props = Object.assign({}, obj); 30 31 result.push(r); 32 33 obj = null; 34 r = null; 35 Utilities.sleep(1000); 36 } 37(以下略)

投稿2022/04/08 10:42

編集2022/04/10 07:13
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

basara

2022/04/11 00:37

遅くなって申し訳ございません。 教えていただいたコードを使用させていただいた所、無事ズレなくなりました! 本当にありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問