ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。エンジニアの日々の開発などの記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

GASとChatGPTを使ってブログ記事をスクレイピングしつつ要約をまとめてもらう。

URLを入力すればそのサイトの要約をまとめてくれると嬉しいですよね。そういうサービスがありますが、無料で使えるものってなかなか見つからないですよね。そこで、今回は自分で実装することにしました

処理の流れとしては以下になります。

  1. 要約してほしいURLを指定
  2. 指定したURLをスクレイピング
  3. スクレイピングしたブログ記事の文章をいい感じに抽出
  4. ChatGPTに要約をしてもらう

これらについて、今回紹介したいと思います。

GASでChatGPTを利用する

まずは、Google Apps Script(以下、GAS)からChatGPTを利用する方法について触れておきます。

www.pnkts.net

こちらの記事で紹介しているので御覧ください。

要約してくれるスクリプトの紹介

では、早速紹介したいと思います。

  1. 要約してほしいURLを指定
  2. 指定したURLをスクレイピング
  3. スクレイピングしたブログ記事の文章をいい感じに抽出
  4. ChatGPTに要約をしてもらう

こちらの流れで紹介します。

1. 要約してほしいURLを指定

URLの指定方法はそのスクリプトを利用する側がいい感じに指定してくれればいいのでここではメソッドの引数にベタ書きするだけにします。

LINEやSlackを利用して、ボットに対してURLを投稿することで要約してもらうってことも可能だと思います。

2. 指定したURLをスクレイピング

次にスクレイピングします。UrlFetchApp.fetch()を利用することでサイトにアクセスしてレスポンスボディを取得することができます。

const response = UrlFetchApp.fetch(url);
const html = response.getContentText();

取得できる文字列はHTML形式なのでここから記事の内容だけをいい感じに抽出しなければいけません。

3. スクレイピングしたブログ記事の文章をいい感じに抽出

上で取得したHTMLから記事の文章だけを抽出する方法についてです。全世界のブログ記事とかが決められたタグやフォーマットで書かれていれば抽出は楽ですが、世の中そんなに甘くありません。そこで、ChatGPTにヒントをもらいました。というか、実装してもらって参考にしました。

Pタグを利用する方法

記事の内容って最近だとほとんどのPタグで囲まれていることが多いと思います。Pタグで囲まれている前提で抽出する方法です。

function scrapeBlogPost(url) {
  // URLからHTMLを取得
  const response = UrlFetchApp.fetch(url);
  const html = response.getContentText();
  
  // Cheerioを使用してHTMLを解析
  const $ = Cheerio.load(html);
  
  // ブログ記事の本文を含むpタグを取得
  const paragraphs = $("p");
  
  // 本文からテキストを抽出
  let text = "";
  paragraphs.each(function() {
    const paragraphText = $(this).text();
    text += paragraphText + "\n";
  });
  Logger.log(text)
  return text;
}

もちろんPタグが利用されてないブログ・サイトは抽出できないので注意です。

もっといい感じに利用したい

もうちょっとChatGPTに質問してみました。

function scrapeBlogPost(url) {
  // URLからHTMLを取得
  const response = UrlFetchApp.fetch(url);
  const html = response.getContentText();
  
  // Cheerioを使用してHTMLを解析
  const $ = Cheerio.load(html);
  
  // 記事のテキストを含む要素を検索
  const articleElement = $("article, div[id*='post'], div[class*='post'], div[class*='article'], div[class*='entry'], div[class*='content']");
  
  // 記事のテキストを抽出
  const text = articleElement.text();
  Logger.log(text.replace(/^\s+|\s+$/g, ''));
  return text;
}

いろんなパターンを書いているんですかね。

Cheerioについて

上で紹介しているスクリプトはCheerioライブラリを利用しています。 GASのライブラリ追加からスクリプトIDが1ReeQ6WO8kKNxoaA_O0XEQ589cIrRvEBA9qcWpNqdOP17i47u6N9M5Xh0を利用しています。

参考サイト: https://www.iehohs.com/gas-cheerio-scraping/

結局どうしたか

今回は2つの方法を紹介しましたが、意外とPタグを利用しているサイトが多かったので、Pタグから文字を抽出する方法を利用することにしました。

※この記事のタイトルにChatGPTを使ってと書いていますが、この実装方法の相談相手として使ったってことではありません。このあとちゃんとOpenAIのAPIを叩いています。

4. ChatGPTに要約をしてもらう

抽出した文章からChatGPTに要約してもらいます。今流行のChatGPTを利用してみたんです。

クラスメソッドさんの以下の記事を参考にGASで実装しました。

dev.classmethod.jp

function chatGpt(text) {
  var url = "https://api.openai.com/v1/chat/completions";
  var apiKey = 'OpenAIのAPI Keyをここに入力する'
  var headers = {
    'Content-Type': 'application/json; charset=UTF-8',
    'Authorization': 'Bearer ' + apiKey,
  };
  
  var systemParameter = '入力された文章を要約してください。\n\
\n\
  制約条件\n\
  ・文章は簡潔にわかりやすく。\n\
  ・箇条書きで3行以内で出力。\n\
  ・1行あたりの文字数は80文字程度。\n\
  ・重要なキーワードは取り逃がさない。\n\
  ・要約した文章は日本語へ翻訳。\n\
\n\
  '
  
  var postData =   {
    "model": "gpt-3.5-turbo",
    "messages": [
      {'role': 'system', 'content': systemParameter},
      {"role": "user", "content": text}
      ]
  };

  var options = {
    'method' : 'post',
    'headers' : headers,
    'payload' : JSON.stringify(postData),
    'muteHttpExceptions':true
  };

  response = UrlFetchApp.fetch(url, options);  
  data = JSON.parse(response.getContentText('UTF-8'));
  Logger.log(data);
  Logger.log(data.choices[0].message.content)

  return data.choices[0].message.content
}

rolesystemを指定することで、前提の条件とかを指定することができます。クラスメソッドさんの記事のほとんど真似してますが、以下のような指定をしています。

  • 文章は簡潔にわかりやすく。
  • 箇条書きで3行以内で出力。
  • 1行あたりの文字数は80文字程度。
  • 重要なキーワードは取り逃がさない。
  • 要約した文章は日本語へ翻訳。

スクリプトまとめ

上で紹介したスクリプトを一つにまとめると以下のようになります。

function scrapeBlogPost(url) {
  // URLからHTMLを取得
  const response = UrlFetchApp.fetch(url);
  const html = response.getContentText();
  
  // Cheerioを使用してHTMLを解析
  const $ = Cheerio.load(html);
  
  // ブログ記事の本文を含むpタグを取得
  const paragraphs = $("p");
  
  // 本文からテキストを抽出
  let text = "";
  paragraphs.each(function() {
    const paragraphText = $(this).text();
    text += paragraphText + "\n";
  });
  Logger.log(text)
  return text;
}

function chatGpt(text) {
  var url = "https://api.openai.com/v1/chat/completions";
  var apiKey = 'OpenAIのAPI Keyをここに入力する'
  var headers = {
    'Content-Type': 'application/json; charset=UTF-8',
    'Authorization': 'Bearer ' + apiKey,
  };
  
  var systemParameter = '入力された文章を要約してください。\n\
\n\
  制約条件\n\
  ・文章は簡潔にわかりやすく。\n\
  ・箇条書きで3行以内で出力。\n\
  ・1行あたりの文字数は80文字程度。\n\
  ・重要なキーワードは取り逃がさない。\n\
  ・要約した文章は日本語へ翻訳。\n\
\n\
  '
  
  var postData =   {
    "model": "gpt-3.5-turbo",
    "messages": [
      {'role': 'system', 'content': systemParameter},
      {"role": "user", "content": text}
      ]
  };

  var options = {
    'method' : 'post',
    'headers' : headers,
    'payload' : JSON.stringify(postData),
    'muteHttpExceptions':true
  };

  response = UrlFetchApp.fetch(url, options);  
  data = JSON.parse(response.getContentText('UTF-8'));
  Logger.log(data);
  Logger.log(data.choices[0].message.content)

  return data.choices[0].message.content
}

これで準備が整いました。

実際に利用してみる

上で作成したプログラムを実際に利用してみます。

対象の記事は、最初の方にも紹介したGASでChatGPTを利用する方法について紹介した記事になります。

www.pnkts.net

function test() {
  var url = 'https://www.pnkts.net/2023/03/21/gas-chatgpt'
  var content = scrapeBlogPost(url);
  var result = chatGpt(content);
  Logger.log(result)
}

このようにして作成したメソッドを呼び出す形で実行してみます。

実行結果は以下になります。

Google Apps Scriptを用いて、OpenAIのChatGPT APIを利用する方法について紹介されています。API Keyを取得し、ChatGPTのスクリプトを呼び出すだけで、自動応答ができることがわかりました。この方法を活用することで、AIを利用した多様な処理が可能になるとのことです。

このように、記事の要約をしてくれました。

最後に

ChatGPTを利用することで、GAS上から対象の記事サイトを取得して要約してもらう処理を作成することができました。無料でここまでの処理を実現できるとは時代が変わりましたね。

これを利用して、無料でSlackボットやLINEボットなどでURLを渡すだけで要約してくれるボットも簡単に作成できるようになりますね。

お問い合わせプライバシーポリシー制作物