CSVファイルから会社名を入手してchatgptによってどの業種かを判断し，結果をCSVファイルに出力する。

# CSVファイルから会社名を入手してchatgptによってどの業種かを判断し，結果をCSVファイルに出力する。
投稿日2024/05/14
ferido2318

ふとCSVにまとめられた会社名をみて，それぞれがどの業種なのかわかるようになれば便利だなあと思い，コードを書いてみた。プログラミング経験のない初学者がかいたコードなので，悪しからず。

具体的にはCSVファイルから会社名を入手し，その会社名をwebスクレイピングで検索し，トップヒットしたサイトのURLからそのサイトのページを入手し，それをchatgptに投げることで判断してもらうというコードである。

全体のコードは以下である。
```
import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
import openai
import os
import csv
from time import sleep
import numpy as np
# CSVファイルを開く
count=0
company=[]
os.chdir(os.path.dirname(os.path.abspath(__file__)))
with open('test1.csv', newline='', encoding='utf-8') as csvfile:
    reader = csv.reader(csvfile)
    # 各行のデータを読み込む
    for row in reader:
        print(row)
        count+=1
        #companyリストにcsvファイルの単語を格納
        company.append(row)
answer_writeCSV=np.zeros((1,2*count), dtype=object)
# companyリストを一つずつ参照
for i in range(0,count):
    sleep(20)
    search_word = f'{company[i]}'
    # 上位から何件までのサイトを抽出するか指定する
    pages_num = 1+1
    print(f'【検索ワード】{search_word}')
    # Googleから検索結果ページを取得する
    url = f'https://www.google.co.jp/search?hl=ja&num={pages_num}&q={search_word}'
    request = requests.get(url)
    # Googleのページ解析を行う
    soup = BeautifulSoup(request.text, "html.parser")
    search_site_list = soup.select('div.kCrYT > a')
    # ページ解析と結果の出力
    for rank, site in zip(range(1, pages_num), search_site_list):
        try:
            site_title = site.select('h3.zBAuLc')[0].text
        except IndexError:
            site_title = site.select('img')[0]['alt']
        site_url = site['href'].replace('/url?q=', '')
        site_url = re.sub("&sa=U.*", "", site_url)
        # 結果を出力する
        print(site_url)
    def extract_text_from_url(url):
        # URLからHTMLを取得
        response = requests.get(url)
        html_content = response.text
        # BeautifulSoupを使用してHTMLを解析
        soup = BeautifulSoup(html_content, "html.parser")
        # 記事の本文を取得
        for script in soup(["script", "style"]):
            script.decompose()
        # テキストの抽出
        text=soup.get_text()
        lines= [line.strip() for line in text.splitlines()]
        text="\n".join(line for line in lines if line)
        return text
    # 使用例
    text = extract_text_from_url(site_url)
    # print(text)
    # 環境変数からAPIキーを取得し、OpenAIライブラリに設定
    openai.api_key = ""
    def classify_company_industry(company_name):
        # APIリクエストを構成
        prompt=f"""「{company_name}」の文章を読んで，この企業が
        A 農業、林業
        B 漁業
        C 鉱業、採石業、砂利採取業
        D 建設業
        E 製造業
        F 電気・ガス・熱供給・水道業
        G 情報通信業
        H 運輸業、郵便業
        I 卸売業、小売業
        J 金融業、保険業
        K 不動産業、物品賃貸業
        L 学術研究、専門・技術サービス業
        M 宿泊業、飲食サービス業
        N 生活関連サービス業、娯楽業
        O 教育、学習支援業
        P 医療、福祉
        Q 複合サービス事業
        R サービス業（他に分類されないもの）
        の中でどこに分類されるか以下の要件を満たすように回答してください。
        1．上の分類の単語のみで回答すること
        3．回答の最後に改行を含むこと
        4．複数の単語の場合は，区切りをカンマでつけて，単語の間に改行を含まないこと"""
        response = openai.ChatCompletion.create(
            model="gpt-4",  # 最新のモデルに更新
            messages = [
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": prompt}
            ],
            max_tokens=200
        )
        # 取得した情報を表示
        response_text=response.choices[0].message.content
        return response_text
    # 企業名を指定
    # 業種分類関数を呼び出し
    answer=classify_company_industry(text)
    print(answer)
    answer_writeCSV[0][2*i]=search_word
    answer_writeCSV[0][2*i+1]  =answer
print(answer_writeCSV)
csv_path = r"C:・・・\結果.csv"
with open(csv_path, 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerows(answer_writeCSV)

```

以下で各部分についての説明をする。

### ライブラリのインポート
```
import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
import openai
import os
import csv
from time import sleep
import numpy as np
```
ここはライブラリをインポートしているところで，requests,beautifulSoupがwebスクレイピングについて，openaiがchatgpt,ほかは便利なライブラリになっている。

### CSVの読み込み
```
count=0
company=[]
os.chdir(os.path.dirname(os.path.abspath(__file__)))
with open('test1.csv', newline='', encoding='utf-8') as csvfile:
    reader = csv.reader(csvfile)
    # 各行のデータを読み込む
    for row in reader:
        print(row)
        count+=1
        #companyリストにcsvファイルの単語を格納
        company.append(row)
answer_writeCSV=np.zeros((1,2*count), dtype=object)
```
前提として会社名しか入っていないCSVファイルを想定しいているので，素直に上から読み込んで，それをcompanyという名のリストに追加している。

### 会社名の検索
```
# companyリストを一つずつ参照
for i in range(0,count):
    sleep(20)
    search_word = f'{company[i]}'
    # 上位から何件までのサイトを抽出するか指定する
    pages_num = 1+1
    print(f'【検索ワード】{search_word}')
    # Googleから検索結果ページを取得する
    url = f'https://www.google.co.jp/search?hl=ja&num={pages_num}&q={search_word}'
    request = requests.get(url)
        # ページ解析と結果の出力
    for rank, site in zip(range(1, pages_num), search_site_list):
        try:
            site_title = site.select('h3.zBAuLc')[0].text
        except IndexError:
            site_title = site.select('img')[0]['alt']
        site_url = site['href'].replace('/url?q=', '')
        site_url = re.sub("&sa=U.*", "", site_url)
        # 結果を出力する
        print(site_url)
```
companyに入っている会社名リストを，for文で回す。会社名を検索し，pages_num=1+1,つまりトップヒットしたページのURLをrequestで取得する。そして，取得したURLを表示する。（そのままだとURLにむだなものがついてしまっているので，site_url=...で処置している）

### URLの解析
```
 # URLからHTMLを取得
        response = requests.get(url)
        html_content = response.text
        # BeautifulSoupを使用してHTMLを解析
        soup = BeautifulSoup(html_content, "html.parser")
        # 記事の本文を取得
        for script in soup(["script", "style"]):
            script.decompose()
        # テキストの抽出
        text=soup.get_text()
        lines= [line.strip() for line in text.splitlines()]
        text="\n".join(line for line in lines if line)
        return text
```
上で得られたURLから，beautifulSoupでHTMLを入手する。そこから，get_textでテキスト本文を得る。

### chatgpt に受け渡し
```
 text = extract_text_from_url(site_url)
    # print(text)
    # 環境変数からAPIキーを取得し、OpenAIライブラリに設定
    openai.api_key = ""
    def classify_company_industry(company_name):
        # APIリクエストを構成
        prompt=f"""「{company_name}」の文章を読んで，この企業が
        A 農業、林業
        B 漁業
        C 鉱業、採石業、砂利採取業
        D 建設業
        E 製造業
        F 電気・ガス・熱供給・水道業
        G 情報通信業
        H 運輸業、郵便業
        I 卸売業、小売業
        J 金融業、保険業
        K 不動産業、物品賃貸業
        L 学術研究、専門・技術サービス業
        M 宿泊業、飲食サービス業
        N 生活関連サービス業、娯楽業
        O 教育、学習支援業
        P 医療、福祉
        Q 複合サービス事業
        R サービス業（他に分類されないもの）
        の中でどこに分類されるか以下の要件を満たすように回答してください。
        1．上の分類の単語のみで回答すること
        3．回答の最後に改行を含むこと
        4．複数の単語の場合は，区切りをカンマでつけて，単語の間に改行を含まないこと"""
        response = openai.ChatCompletion.create(
            model="gpt-4",  # 最新のモデルに更新
            messages = [
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": prompt}
            ],
            max_tokens=200
        )
        # 取得した情報を表示
        response_text=response.choices[0].message.content
        return response_text
    # 企業名を指定
    # 業種分類関数を呼び出し
    answer=classify_company_industry(text)
    print(answer)
    answer_writeCSV[0][2*i]=search_word
    answer_writeCSV[0][2*i+1]  =answer
print(answer_writeCSV)
csv_path = r"C:・・・\結果.csv"
with open(csv_path, 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerows(answer_writeCSV)

```
上で得られたテキストをchatgptに投げる。ここでの文法は適宜参照してもらいたいが，promptの部分で命令文を指定し，messageの部分で実際にchatgptに渡している。最後に得られた回答をCSVにまとめることで完成。

### 問題点
このコードの問題点として，chatgpt APiの利用トークン量が多くなってしまっていることだ。これは，webページの本文を丸ごとchatgptに渡して文字数が多くなっていることが原因だと考えられる。この解決方法として，業種コードに関係ありそうな部分を改めて抜き出すか，取得するテキストを検索スニペット(検索した時にでてくるwebページのタイトルのしたにある説明文みたいなもの)を代わりに取得することがあげられる。ただ，前者についてはすべての業種に当てはまるキーワードを考え出さなければならないか，機械学習を随時導入しなければならないのと，後者については，私自身HTMLの知識があさいのはあるが，ページによってタグの名前が違うのでうまく抜き出せるかわからないことがある。

なにはともあれ，問題は抱えつつもCSVにまとめられた企業の業種分類はできた。