投稿

9月, 2024の投稿を表示しています

GASでスクレイピング 〜天才ア○バ様の教え〜

イメージ
フハハハハ!お前たち愚か者には到底理解できぬだろうが、我こそは天才、ア○バ様だ!このア○バが、Google Apps Script(GAS)を使ってログインが必要なウェブページをスクレイピングする術を伝授してやろう!私のような天才にかかれば、こんなことは児戯にも等しい! スクレイピングとは何かだと?フフフ… 愚かな質問だが、教えてやる。スクレイピングとは、ウェブページのデータを自動で引きずり出す技だ!手動でポチポチやるのはもはや古代の技術。我、ア○バが編み出す自動化こそ真の覇道だ。だがな、ログインを必要とするページでは、少しばかり知恵を使わねばならぬ。フハハ!見ていろ、私が如何にしてその壁を打ち破るかを! ステップ1:ログインフォームを解析する…当然だろう! フフフ、ログインページに飛び込む前に、まずは敵(ログインフォーム)を解析せねばならん。愚か者どもは「ボタンを押すだけ」などと考えておるが、天才たる○ミバ様はそんなものに惑わされぬ。よく見ていろ、これが解析の手順だ! ログインページに潜入 : 私のような天才は、Chromeを開いてログインページに足を踏み入れるのだ。 開発者ツールの召喚 : F12 だ。これでログインフォームの裏側、つまりその構造を暴いてやるのだ。 Networkタブで観察 : フハハ、ここでフォームがどのURLにデータを送信しているかを見つけるのだ!愚か者には見えぬが、私には見える…。 POSTデータの確認 : ログインボタンを押して送信されるデータ、すなわちユーザー名( username )やパスワード( password )がどのように送られるかを知るのだ。 ステップ2:ログインリクエストをぶち込む!フハハハ! さて、ログインフォームの弱点を見抜いた今、私○ミバがログインのリクエストを飛ばしてやろう。愚かなセキュリティなど我にとっては無力よ! const loginUrl = 'https://example.com/login' ; // ログインページのURL const loginPayload = { ...

GASでPDFからテキストを抽出する方法 〜大学教授の戦い編〜

イメージ
今どきの学生というのは、なかなか手の込んだやり方で手抜きをする。レポートの提出時に、わざわざ一度画像に変換し、それを貼り付けてPDFにして提出してくる輩が現れたのだ。それでコピペがバレないとでも思っているのだろうか。 Wordファイルからコピペを検出するツールが教授仲間で共有され、さほど手間をかけずにコピペレポートの判定が出来ることが学生内にも広まってきたことから、新たな工夫が生まれたのだろう、まるで「先生も頑張ってくださいね」とでも言わんばかりに、PDF形式で提出してくる。だが、私はそんな手段で簡単に引き下がる教授じゃない。GASを使って、PDFの中からテキストを引っ張り出し、その手抜き具合を暴く方法なんていくらでもある。今回は、そんな学生たちとの「戦い」を念頭に、PDFからテキストを抽出する方法を紹介する。 1. Google Drive APIを使ったOCRでテキスト抽出 状況説明 最も簡単な方法は、Google Drive APIのOCR機能を使うことだ。学生が「どうせ画像化したPDFなら先生も諦めるだろう」と思って提出した画像PDFからも、Drive APIの力でテキストはすべて抽出できる。彼らの「安易な策」はこれでほぼ通用しない。 実装方法 以下のコードでは、GoogleドライブにアップロードされたPDFをOCRで処理し、文字を抽出する。 function extractTextFromPdfWithOCR ( fileId ) { const file = DriveApp . getFileById ( fileId ) ; const resource = { title : file . getName ( ) , mimeType : MimeType . GOOGLE_DOCS } ; const blob = file . getBlob ( ) ; const docFile = Drive . Files . create ( resource , blob , { ocr : true } ) ; const doc = DocumentApp . openById ...

GASのさらに高度なテクニック:非同期処理、プロパティサービス、Webhookチェーン

イメージ
さて、今度はさらに深淵な自動化のテクニックに手を出すとしよう。キーワードは「非同期処理」「プロパティサービス」「Webhookチェーン」の3つだ。どうだい?ちょっと本格的なプログラミングっぽくてワクワクするだろう? ディープトリック・その1:非同期処理で複数のタスクを並列に処理する 実際には、GAS(Google Apps Script)自体はJavaScriptのように非同期処理(Promiseやasync/await)を直接扱えないが、それでも複数のタスクをできる限り同時に進行させるテクニックは存在する。この手法は、特に複数のAPIリクエストや外部サービスとの通信が絡む場合、プロセスのスピードアップに大きく貢献する。 1. 複数のリクエストを一斉に実行する理由 通常、APIリクエストを順番に処理する場合、1つのリクエストが完了するまで次のリクエストは待たされる。APIへの呼び出し時間が各々1〜2秒でも、連続するリクエストが5つもあれば、簡単に10秒以上かかってしまう。 これを効率化するために、リクエストを一斉に発行して処理する方法がGASにはある。GASはURLFetchAppのリクエストを並行して実行できるため、それらをリストにまとめ、処理が完了するまで待たずに次のリクエストを発行することで、結果的にプロセス全体を短縮できる。 function fetchMultipleData ( ) { const urls = [ 'https://api.example.com/data1' , 'https://api.example.com/data2' , 'https://api.example.com/data3' ] ; // 複数のAPIリクエストを一斉に発行 const fetchData = urls . map ( url => { return UrlFetchApp . fetch ( url ) ; // 各APIからデータ取得 } ) ; // 取得したデータを一度に処理 const results = fetchData . ...

GASでさらに極める自動化:外部APIとリアルタイム連携

イメージ
今回のテーマは「さらにディープなトリック」。これまでのトリガーや自動化、エラー処理なんてのは序章に過ぎない。今度は自動化を究極まで突き詰めて、GASの限界を越えてやろうじゃないか。API連携や外部データの取込み、リアルタイムな自動化を駆使して、より複雑な処理をいかに軽々とこなすか。いくつかの例をお披露目しよう。 ディープトリック1:外部APIとのシームレスな連携 外部APIを使ってリアルタイムでデータを取得し、スプレッドシートに反映させるトリックを紹介する。今回使うのは、 OpenWeather API という天気情報を提供するAPIだ。これを用いて、特定の都市の天気情報をスプレッドシートに自動で反映させる。 まずは、OpenWeather APIにサインアップしてAPIキーを取得しよう( こちら から)。APIキーは後でスクリプト内で使う。 function fetchWeatherData ( ) { const apiKey = 'YOUR_API_KEY' ; // 取得したAPIキー const city = 'Tokyo' ; // 対象都市 const apiUrl = `http://api.openweathermap.org/data/2.5/weather?q= ${ city } &appid= ${ apiKey } &units=metric` ; const response = UrlFetchApp . fetch ( apiUrl ) ; const jsonData = JSON . parse ( response . getContentText ( ) ) ; const sheet = SpreadsheetApp . getActiveSpreadsheet ( ) . getSheetByName ( 'WeatherData' ) ; sheet . getRange ( 'A1' ) . setValue ( `Weather in ${ city } ` ) ; sheet . getRange (...

GASでの高度な自動化トリック 〜自動化の裏側に潜む罠を乗り越える方法(探偵編その2)〜

イメージ
今回は「高度な自動化のトリック」について、掘り下げてみる。スクリプトがただ動くだけじゃ満足できない連中のために、もう少し高度な自動化手法を披露してやろう。データの正規化や整理なんて序章に過ぎない。俺たち探偵は、問題が発生したときにこそ腕が試される。自動化の罠にハマらないための秘訣ってやつだ。 トリック1:複雑なフローを自動化する データ整理が一段落した後、クライアントはきっと次の無理難題を押し付けてくる。例えば、複数のシートやファイルに分散しているデータを一括で集めて、集約してくれってな。こんなときに役に立つのが**「トリガーチェーン」**という高度なテクニックだ。 トリガーチェーンとは? 複数のスクリプトやフローを連携させるためのテクニックだ。一つのスクリプトが完了したら、次のスクリプトを実行するようにトリガーを設定しておく。時間トリガーだけじゃなく、 カスタムトリガー も使って、まるでパズルのピースをはめるように自動化を仕込む。 例:データ集約のフロー シートAからデータを抽出。 シートBからもデータを引っ張り出す。 データを集約して、新しいシートCに書き込む。 こんなフローを実現するためのスクリプトは、こんな感じになる。 function extractDataFromSheetA ( ) { const sheetA = SpreadsheetApp . getActiveSpreadsheet ( ) . getSheetByName ( 'SheetA' ) ; const dataA = sheetA . getDataRange ( ) . getValues ( ) ; // ここでデータ処理を行う // ... // 次のステップに進むためにカスタムトリガーを設定 ScriptApp . newTrigger ( 'extractDataFromSheetB' ) . timeBased ( ) . after ( 1000 ) // 1秒後に次のスクリプトを実行 . create ( ) ; } function ...

GASの時間トリガー設定 〜スプレッドシートのデータ正規化は俺に任せろ(探偵編)〜

イメージ
またクライアントからだ。スプレッドシートに山積みのデータをぶち込んで「このデータを自動的に整理してくれ」っていう依頼。分かってるよ、手作業でなんかやってられないだろうさ。だからこそ、俺たちが必要なんだ。いやまてよ、これって本当に探偵に依頼する仕事なのか・・・?まあいいだろう。猫を探すのもデータを探すのも共通するコツってものがあるものさ。 さて、スプレッドシートでデータを正規化――つまり、同じフォーマットに揃えて整理するためには、Google Apps Script(GAS)の「時間トリガー」を仕込むのがベストだ。時間が来たら、俺たちのスクリプトが自動で動き出すってわけだ。簡単そうに聞こえるか? まぁ、実際はそうでもないが、ここではその手順を教えてやる。 ステップ1:GASエディタを開く まずは、GASエディタにアクセスしなきゃ話が始まらない。スプレッドシートの 拡張機能 > Apps Script から行ける。この操作くらいは簡単だろ?探偵稼業でも、まずは現場に向かうところから始まる。手順はこうだ: データが入ったスプレッドシートを開け。 メニューから「 拡張機能 」をクリック。 「 Apps Script 」を選択。 ステップ2:スクリプトを書く さて、クライアントのスプレッドシートに放り込まれたデータは、まるで乱雑に積み上げられた書類の山だ。俺たちがやるのは、それを自動で整理するスクリプトを書いてやることだ。今回のケースでは、重複するデータを消して、空白を埋めて、何とかクライアントが使える形に整える。 たとえば、こんな感じのスクリプトだ。 function normalizeData ( ) { const sheet = SpreadsheetApp . getActiveSpreadsheet ( ) . getActiveSheet ( ) ; const data = sheet . getDataRange ( ) . getValues ( ) ; // 重複を取り除いて、データを整形 const normalizedData = [ ] ; const uniqueCheck = new Set ( ) ; ...

GASでgoogleフォームと連携しよう 〜先生の悩みを減らす方法(教師編)〜

イメージ
縁あって、週に一度教壇に立つことになった。自分が中学生、高校生だった頃には想像だにしなかった、教員のおかれている授業以外の様々な状況に振り回されている。そう、教員とは、意味もなく増え続ける書類やなぜか上から目線の保護者への対応に翻弄され、時に授業という本来の仕事を忘れがちな職業なのだ。それでもやってくる毎日の授業、宿題の確認、アンケートの集計…。 おっと、つい愚痴をもらしてしまった。しかし、今やそのいくつかはGoogleフォームを使うことで解決する。「え?そうなの?本当に?」と疑いたくなるかもしれない。しかし教員だってIT化の恩恵に与りたいと思うのはアタリマエのことなのだ。まあなんだ、今後も教員を続けるつもりなら、せめて保護者への対応に頭を悩ませる十分な時間を確保しないことにはどうにもなるまい。 目的 今回の目的は、Googleフォームから得た生徒のデータを自動的に処理し、提出状況の確認や、面倒な集計作業を簡素化することだ。要するに、これで少しでも仕事が楽になるのなら万々歳だ、ということだ。 準備 Googleフォーム :生徒が宿題を提出するための質問を作成し、提出された回答をスプレッドシートに保存する。 スプレッドシート :フォームの回答を保存する場所で、ここにGASで少し小細工を加えることになる。 GASエディタ :スプレッドシートの 拡張機能 > Apps Script から、GASエディタを開く。これから書くコードが、あなたの作業を一部救ってくれる…はず。 コードの説明 宿題の提出状況をリアルタイムで確認する方法 フォームを使えば、生徒たちは宿題を提出しやすくなる…はずだが、実際に全員が期限通りに提出することは稀である。そこで、GASを使って未提出者をすぐに捕捉し、通知する仕組みを作ろう。 function onFormSubmit ( e ) { const sheet = SpreadsheetApp . getActiveSpreadsheet ( ) . getActiveSheet ( ) ; const responses = e . values ; // 新しい回答 const time...