4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

相棒のChatGPTと画像保存の自動化でコスト削減!

Last updated at Posted at 2024-07-23

「面倒くさい。でも、やらねば…」をなくしたい

 仕事をしていると、単純作業で面倒だけど、必要な作業、みたいなことってありません?
 私事ですが、今新しいアプリケーションを各店舗へ展開しています。
展開する事前準備として、100以上の画像データを保存する、といった「面倒くさい。でも、やらねば…」な作業が発生していて、萎えています😑
しかも、これがあと60回もやらなくてはいけず、想定作業時間は120時間😱 さすがに非効率なので、派遣スタッフを雇う予定でした。

そんなとき、ChatGPTに出会ったのです✨

image.png

webの画像データを自動保存するツールを開発📁

<できること>

 webページのロゴ画像データを指定フォルダへ自動で保存できます✨
image.png

<実際のコード>

downloadLogoImages
function downloadLogoImages() {
  const url = "webページのURL";
  const logoFilenamePattern = /logo\.png/;

  try {
    // ウェブページのHTMLを取得
    const html = UrlFetchApp.fetch(url).getContentText();
  
    // 画像URLを抽出
    const imgUrls = extractImageUrls(html, logoFilenamePattern, url);
    
    // 画像をダウンロード
    imgUrls.forEach(function(imgUrl) {
      downloadImage(imgUrl);
    });

  } catch (e) {
    Logger.log("Error: " + e.message);
  }
}

function extractImageUrls(html, pattern, baseUrl) {
  const imgUrls = [];
  const regex = /<img[^>]+src="([^">]+)"/g;
  let match;
  while ((match = regex.exec(html)) !== null) {
    let src = match[1];
    if (pattern.test(src)) {
      // 絶対URLに変換
      src = convertRelativeToAbsoluteUrl(baseUrl, src);
      imgUrls.push(src);
    }
  }
  return imgUrls;
}

function convertRelativeToAbsoluteUrl(base, relative) {
  if (relative.startsWith('http')) {
    return relative;
  }
  if (relative.startsWith('/')) {
    const url = base.split('/');
    return url[0] + '//' + url[2] + relative;
  }
  return base + relative;
}

function downloadImage(url) {
  try {
    const response = UrlFetchApp.fetch(url);
    const blob = response.getBlob();
    const filename = url.split('/').pop();
  
    // 画像をGoogle Driveに保存
    const folder = DriveApp.getFolderById('YOUR_FOLDER_ID'); // 保存先フォルダのIDを指定
    folder.createFile(blob).setName(filename);

  } catch (e) {
    Logger.log("Error downloading image from " + url + ": " + e.message + "\nStack: " + e.stack);
  }
}

コードの作り方

<使ったツール>

 ・ChatGPT
 ・Google Apps Script
 ・Google Drive

<事前準備>

 GoogleDriveに画像データを保存するフォルダを作成する。

手順①:ChatGPTにやりたいことを伝えてコードをかいてもらう

image.png

手順②:ChatGPTの案内通りに実行する

①でChatGPTにコードを聞くと、実行手順も返してくれます。
その通り、実際に実行してみます。
image.png

Google Driveの保存先フォルダID取得方法もChatGPTが教えてくれる!

image.png

手順③:ひたすらChatGPTと向き合う

ここからが長かった・・・😂
ChatGPTの機嫌によっては上手く実行できないこともあるので、エラーが出る都度、ChatGPTに新たなコードを書いてもらいます。
(私はこのtry&errorを数十回繰り返しました)

▼イメージ

image.png

ChatGPTのプロンプトはできるだけ詳しく、具体的に!
提案してくれた方法を行ってもエラーが出たら、それも伝えてみると、どこに問題があるか調べる方法を提案してくれる👏

画像ファイルの名前をつける

相棒(ChatGPT)のおかげで予定よりも早く目的を達成できたので、画像データを保存する際、ファイル名を店名にしてもらうよう、要件を追加しました。
image.png

ここでもエラーがでるけど、めげずに相棒(ChatGPT)に頼る!

<完成したコード>

downloadLogoImages
function downloadLogoImages() {
  const url = "webページのURL";
  const logoFilenamePattern = /logo\.png/;
  
  try {
    Logger.log("Fetching HTML from: " + url);
    // ウェブページのHTMLを取得
    const html = UrlFetchApp.fetch(url).getContentText();
    Logger.log("HTML fetched successfully");

    // HTML全体を分割してログに出力(デバッグ用)
    for (let i = 0; i < html.length; i += 1000) {
      Logger.log("HTML part: " + html.substring(i, i + 1000));
    }

    // 画像URLとショップ名を抽出
    const imgData = extractImageUrlsAndNames(html, logoFilenamePattern, url);
    
    Logger.log("Extracted image data: " + JSON.stringify(imgData));
    
    // 画像をダウンロード
    imgData.forEach(function(data) {
      Logger.log("Downloading image from: " + data.url + " with name: " + data.shopName);
      downloadImage(data.url, data.shopName);
    });

  } catch (e) {
    Logger.log("Error: " + e.message);
  }
}

function extractImageUrlsAndNames(html, pattern, baseUrl) {
  const imgData = [];
  const regex = /<li class="item">.*?<img[^>]+src="([^">]+)".*?<h3 class="shopName">\s*([^<]+)\s*<\/h3>/gs;
  let match;
  while ((match = regex.exec(html)) !== null) {
    let src = match[1];
    let shopName = match[2];
    if (pattern.test(src)) {
      // 絶対URLに変換
      src = convertRelativeToAbsoluteUrl(baseUrl, src);
      imgData.push({ url: src, shopName: sanitizeFileName(shopName) });
    }
  }
  return imgData;
}

function convertRelativeToAbsoluteUrl(base, relative) {
  if (relative.startsWith('http')) {
    return relative;
  }
  if (relative.startsWith('/')) {
    const url = base.split('/');
    return url[0] + '//' + url[2] + relative;
  }
  return base + relative;
}

function sanitizeFileName(name) {
  // ファイル名として使えない文字を置換
  return name.replace(/[\/:*?"<>|]/g, '_');
}

function downloadImage(url, shopName) {
  try {
    Logger.log("Fetching image from URL: " + url);
    const response = UrlFetchApp.fetch(url);
    const blob = response.getBlob();
    const filename = shopName + '.png';
    
    Logger.log("Saving image as: " + filename);
    // 画像をGoogle Driveに保存
    const folder = DriveApp.getFolderById('YOUR_FOLDER_ID'); // 保存先フォルダのIDを指定
    folder.createFile(blob).setName(filename);
    Logger.log("Image saved successfully");

  } catch (e) {
    Logger.log("Error downloading image from " + url + ": " + e.message + "\nStack: " + e.stack);
  }
}

<フォルダ>

image.png

このツールを開発した結果…

冒頭でも触れましたが、ChatGPTのおかげで120時間を短縮することができました🤝(約2,300円/H×120H=276,000円相当👏)

ChatGPTを使う際の注意点💡

今回、成し遂げたいことにおいては、粘り強くChatGPTへ問いかけたので、基本的には実現ができたので良かったですが、ChatGPTを活用する上で学んだこととして、何度も繰り返していると同じスクリプトを案内されることがあるため、都度、スクリプト内容については自身で確認する必要性を感じました。

改善したいところ

今回はGASを使ってやってみたため、Google Driveへの保存が必須だったが、容量の問題もあるため、デスクトップフォルダなどに格納できるようにしたい…!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?