XMLのスクレイピングをGASでしてます
XmlからXmlServiceを使用して取得してスプレッドシートに保存できました。
昭和三十四年法律第百二十一号←修正しました。
の内容をスプレッドシートに保存しました。
別の条文も取得しました。
スクレイピングの内容が多い時6分以上かかる場合があり、
トリガーを使って6分以上の処理をできるようにコードを書いています。
トリガーを自動で再開できるコードにしたい。
Google Apps Script で6分以上の処理をする
このサイトのコードを参考にしました。
コードの内容は5分で実行を一旦停止し、1分後に途中から再開するという設定です。
発生している問題・エラーメッセージ
スクレイピングが始まらず実行ログで完了になる。
該当のソースコード
function func() { var startTime = new Date() var sheet = SpreadsheetApp.openById("*********").getSheetByName("**"); let url = 'https://elaws.e-gov.go.jp/api/1/lawdata/昭和三十四年法律第百二十一号'; //////↑修正しました let xml = UrlFetchApp.fetch(url).getContentText(); let document = XmlService.parse(xml); let root = document.getRootElement(); const applData = root.getChild("ApplData"); const lawFullText = applData.getChild("LawFullText"); const law = lawFullText.getChild("Law"); const lawBody = law.getChild("LawBody"); const mainProvision = lawBody.getChild("MainProvision"); //////参考サイトのコード var properties = PropertiesService.getScriptProperties(); //途中経過保存用 var startRowKey = "startRow"; //何行目まで処理したかを保存するときに使用するkey var triggerKey = "trigger"; //トリガーIDを保存するときに使用するkey //途中から実行した場合、ここに何行目まで実行したかが入る var startRow = parseInt(properties.getProperty(startRowKey)); //////条文取得コード const chapters = mainProvision.getChildren("Chapter"); chapters.forEach(function(chapter) { const articles = chapter.getChildren("Article"); articles.forEach(function(article){ var lastrow = sheet.getLastRow(); var recordrow = lastrow + 1; //////参考サイトのコード var rows = sheet.getDataRange().getValues(); for(var i = startRow; i < rows.length; i++){ var diff = parseInt((new Date() - startTime) / (1000 * 60)); if(diff >= 5){ //5分経過していたら処理を中断 properties.setProperty(startRowKey, i); //何行まで処理したかを保存 setTrigger(triggerKey, "func"); //トリガーを発行 return; } //////*条文取得コード* const articleCaption = article.getChild("ArticleCaption"); const articleTitle = article.getChild("ArticleTitle"); const paragraphs = article.getChildren("Paragraph"); if (articleCaption != null){ sheet.getRange("A" + recordrow).setValue(articleCaption.getText()); } sheet.getRange("B" + recordrow).setValue(articleTitle.getText()); if (paragraphs != null){ paragraphs.forEach(function(paragraph){ const paragraphNum = paragraph.getChild("ParagraphNum"); const paragraphSentence = paragraph.getChild("ParagraphSentence"); sheet.getRange("C" + recordrow).setValue(paragraphNum.getValue()); sheet.getRange("F" + recordrow).setValue(paragraphSentence.getValue()); recordrow = recordrow + 1; const items = paragraph.getChildren("Item"); if (items !== null) { items.forEach(function (item) { const itemtitle = item.getChild("ItemTitle"); sheet.getRange("D" + recordrow).setValue(itemtitle.getText()); const itemSentence = item.getChild("ItemSentence"); sheet.getRange("F" + recordrow).setValue(itemSentence.getValue()); recordrow = recordrow + 1; const columns = itemSentence.getChildren("Column"); if (columns !== null) { columns.forEach(function (column) { sheet.getRange("F" + recordrow).setValue(column.getText()); }) } const subitem1s = item.getChildren("Subitem1"); if (subitem1s !== null) { subitem1s.forEach(function (subitem1) { const subitem1Title = subitem1.getChild("Subitem1Title"); sheet.getRange("D" + recordrow).setValue(subitem1Title.getText()); const subitem1Sentences = subitem1.getChildren("Subitem1Sentence"); subitem1Sentences.forEach(function (subitem1Sentence) { sheet.getRange("F" + recordrow).setValue(subitem1Sentence.getValue()); }); const subitem2s = subitem1.getChildren("Subitem2"); if (subitem2s !== null) { subitem2s.forEach(function (subitem2) { const subitem2Title = subitem2.getChild("Subitem2Title"); sheet.getRange("D" + recordrow).setValue(subitem2Title.getText()); const subitem2Sentences = subitem2.getChildren("Subitem2Sentence"); subitem2Sentences.forEach(function (subitem2Sentence) { sheet.getRange("F" + recordrow).setValue(subitem2Sentence.getValue()); }); const subitem3s = subitem2.getChildren("Subitem3"); if (subitem3s !== null) { subitem3s.forEach(function (subitem3) { const subitem3Title = subitem3.getChild("Subitem3Title"); sheet.getRange("D" + recordrow).setValue(subitem3Title.getText()); const subitem3Sentences = subitem3.getChildren("Subitem3Sentence"); subitem3Sentences.forEach(function (subitem3Sentence) { sheet.getRange("F" + recordrow).setValue(subitem3Sentence.getValue()); }); }) } }) } }) } }) } //////↑かっこ追加修正しました。 }) } } //////*参考サイトのコード* //全て実行終えたらトリガーと何行目まで実行したかを削除する deleteTrigger(triggerKey); properties.deleteProperty(startRowKey); }) }) } //指定したkeyに保存されているトリガーIDを使って、トリガーを削除する function deleteTrigger(triggerKey) { var triggerId = PropertiesService.getScriptProperties().getProperty(triggerKey); if(!triggerId) return; ScriptApp.getProjectTriggers().filter(function(trigger){ return trigger.getUniqueId() == triggerId; }) .forEach(function(trigger) { ScriptApp.deleteTrigger(trigger); }); PropertiesService.getScriptProperties().deleteProperty(triggerKey); } //トリガーを発行 function setTrigger(triggerKey, funcName){ deleteTrigger(triggerKey); //保存しているトリガーがあったら削除 var dt = new Date(); dt.setMinutes(dt.getMinutes() + 1); //1分後に再実行 var triggerId = ScriptApp.newTrigger(funcName).timeBased().at(dt).create().getUniqueId(); //あとでトリガーを削除するためにトリガーIDを保存しておく PropertiesService.getScriptProperties().setProperty(triggerKey, triggerId); }
試したこと
初めは参考サイトの/* ここでメイン処理 */の部分にXmlServicしたコードを添付しましたが、
同じエラーで反応せず、
eachの箇所が悪くてループとトリガーに設定にならないのかと思い、
添付したコードにしてみましたがうまくいきませんでした。
補足情報(FW/ツールのバージョンなど)
コードが長く読みにくくてすみません。
ヒントなど教えていただけないでしょうか。
回答1件
あなたの回答
tips
プレビュー