WORKS

実績・制作事例

サイトにチャットボット設置

8. 表示ページ以外の重要情報(会社概要、料金等)も込みで会話できるようにする

今回のチャットボットでは、表示しているウェブページの内容以外に、事前に用意したテキスト情報もリソースとして使用しますが、このテキスト情報として、他のウェブページの内容をあらかじめテキストにして持っておくようにします。
そのために、ウェブページをスクレイピングした後、中の文字列をテキストのみの情報に変換し、それをテキストデータとして格納する処理を作ります。
 
cors_config.jsonファイルの内容に基づき、指定されたウェブページをスクレイピング後、中の文字列をjson, txtファイルとして保存するプログラム
update_extra.py

#!/usr/bin/env python3
import os
import json
import requests
from bs4 import BeautifulSoup
from openai import OpenAI

# 環境変数 OPENAI_API_KEY を必須
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
if not client:
    raise ValueError("Missing OPENAI_API_KEY environment variable")

BASE = os.path.dirname(__file__)
CONFIG_PATH = os.path.join(BASE, 'cors_config.json')
EXTRA_BASE  = os.path.join(BASE, 'extra')


def fetch_text_only(url):
    r = requests.get(url, timeout=15)
    r.raise_for_status()
    soup = BeautifulSoup(r.text, 'html.parser')
    # <article> を優先
    target = soup.select_one('article') or soup.body
    text = '\n'.join(
        line.strip() for line in target.get_text(separator='\n').splitlines() if line.strip()
    )
    return text


def structure_content(text):
    # OpenAI を使ってテキストを体系化したJSONに変換
    system_prompt = (
        "以下の原文から、キーと値のペアで体系的に情報を抽出し、\n"
        "JSONオブジェクトとして出力してください。\n"
        "見出しやセクション名をキーに、対応する内容を値としてください。"
    )
    user_prompt = text[:3000]  # 長すぎる場合は先頭3000文字まで

    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user",   "content": user_prompt}
        ],
        temperature=0.0,
        max_tokens=800
    )
    # レスポンスからJSONを抽出
    content = resp.choices[0].message.content.strip()
    try:
        data = json.loads(content)
    except json.JSONDecodeError:
        # JSON パース失敗時は生テキストを返す
        return None, content
    return data, None


def main():
    # 設定読み込み
    with open(CONFIG_PATH, encoding='utf-8') as f:
        cfg = json.load(f)

    for site in cfg.get('sites', []):
        token     = site['token']
        extra_dir = site.get('extra_dir')
        files     = site.get('extra_files', [])
        if not extra_dir or not files:
            continue

        target_dir = os.path.join(EXTRA_BASE, extra_dir)
        os.makedirs(target_dir, exist_ok=True)

        for ef in files:
            fname = ef.get('filename')
            url   = ef.get('url')
            if not fname or not url:
                continue
            try:
                print(f"[{token}] Fetching {url} → {fname}")
                text = fetch_text_only(url)
                # 本文テキストをそのまま保存
                text_path = os.path.join(target_dir, fname)
                with open(text_path, 'w', encoding='utf-8') as fw:
                    fw.write(text)

                # 体系化 JSON 生成
                json_data, raw = structure_content(text)
                json_fname = fname.replace('.txt', '.json')
                json_path = os.path.join(target_dir, json_fname)
                with open(json_path, 'w', encoding='utf-8') as fj:
                    if json_data:
                        json.dump(json_data, fj, ensure_ascii=False, indent=2)
                    else:
                        # パースできなかった場合、生テキストを comments フィールドに
                        json.dump({"unstructured": raw}, fj, ensure_ascii=False, indent=2)

            except Exception as e:
                print(f"[{token}] ERROR fetching {url}: {e}")

if __name__ == '__main__':
    main()

次にこのpythonファイルを実行するためのモジュールをインストールします。

sudo apt update
sudo apt install -y python3-venv python3-full

cd /var/www/chatbot

python3 -m venv venv
source venv/bin/activate

pip install beautifulsoup4 requests

deactivate

これでupdate_extra.pyが実行できるようになりました。
次にこのupdate_extra.pyがサービス再起動のたびに起動するようにします。
定期的にウェブページの内容が書き換わることを想定し、サービス再起動のたびに生成しなおすようにするためです。
(CRONに設定し定期的に実行する形でも構いませんし、一回実行したらそれで良いという方はご自身で一度実行するだけでOKです。その場合はここから以下の設定は不要です。)

sudo nano /etc/systemd/system/chatbot.service

1行追加します。

[Unit]
Description=Chatbot Service
After=network.target

[Service]
User=www-data
WorkingDirectory=/var/www/chatbot
ExecStartPre=/var/www/chatbot/venv/bin/python /var/www/chatbot/update_extra.py    <-ここ追加
ExecStart=/var/www/chatbot/venv/bin/gunicorn --chdir /var/www/chatbot --bind unix:/var/www/chatbot/chatbot.sock chat:app
Restart=always

[Install]
WantedBy=multi-user.target
EOF

最後にsystemdに設定を反映してサービスを再起動

sudo systemctl daemon-reload
sudo systemctl restart chatbot

sudo systemctl status chatbot

するとupdate_extra.pyが実行され、しばらくするとcors_config.jsonに記載したextraディレクトリにjson, txtファイルが生成されます。
中身を確認して、取得したウェブページの内容だけが書かれていれば無事完了です。
 
 
※ なお、ここでは自動でテキストファイルを生成しましたが、べつに自動で生成しなければいけないわけではありません。ご自身で手動でテキストファイルを作っておく形でも構いません。