【ChatGPT】Webブラウジングプラグイン：サイトクロールのリクエスト情報を確認する

## なに？
ChatGPTのWeb Browsingプラグインが、ウェブサイトをクロールする際のリクエスト情報の確認方法です。

ローカルでWebサーバーを立て、ngrokで公開。その上で、プラグインを使ってアクセスし、生成されるアクセスログを見ていきたいと思います。


## ステップ
1. **Webサーバーの準備**
    - ローカル環境でPythonを用いてWebサーバーを立てます。
1. **トンネリングの実行**
    - ngrokを使用してローカルWebサーバーをトンネリングし、外部ネットワークに公開します。
1. **Web Browsingプラグインの使用**
    - GPT-4のWebインターフェースからWeb Browsingプラグインを選択し、先ほど公開したWebサイトへアクセスします。
1. **アクセスログの確認**
    - アクセスの結果として生成されるアクセスログを詳細に観察し、どのような情報が送信されているのかを理解します。

## Webサーバーの準備
このステップではPythonを使用してローカルWebサーバーを設立し、アクセス時にログをコンソールに出力する簡易的なコードを作成します。

サーバー側のコード
まず、`header_print_server.py`というPythonファイルを作成します。
このファイルではHTTPリクエストのヘッダーを受け取り、それらをコンソールに出力するサーバーを実装します。

```python
import http.server
import socketserver
import os

# Root Dir
os.chdir("public")

# HTTPリクエストを処理
class MyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        # 受信したHTTPヘッダを表示
        print(self.headers)

        # 親クラスのdo_GETメソッドを呼び出す
        super().do_GET()

# ハンドラを設定
handler = MyHTTPRequestHandler

# サーバー起動（ポート80で待受け）
with socketserver.TCPServer(("", 80), handler) as httpd:
    print("Serving at port 80")
    httpd.serve_forever()
```

### index.htmlの作成
次に、Webサーバーが提供するコンテンツを定義するための簡単なHTMLファイルを作成します。
（中身はなんでも良いです）

```
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
```

### ファイル配置
作成したHTMLファイルは、公開用ディレクトリとして指定するpublicディレクトリ内に設置します。
その結果、以下のようなディレクトリ構造ができ上がります。


```
./
├── header_print_server.py
└── public
    └── index.html
```

この段階での準備は以上。
次に、このローカルWebサーバーを外部ネットワークに公開していきます。


## ローカルWebサーバーの公開
ChatGPTのBrowsingプラグインがアクセスできるように、**ローカルで動作しているWebサーバーを外部ネットワークに公開**する必要があります。

ここでは、ngrokというツールを使用してこの作業を行います。

### ngrokの設定
**ngrok**はローカルネットワーク上のサーバーをインターネット上に公開することを可能にするツールです。

今回はこのツールを使用します。具体的なインストール方法は以下のスクラップを参照してください。

https://zenn.dev/bon/scraps/769807474ee951


### サーバーの公開

まず、作成したPythonファイルを実行し、ローカルでWebサーバーを起動します。

```bash
python header_print_server.py
```

次に、`ngrok`を使用して起動したWebサーバーを公開します。

```bash
ngrok http 80
```

成功すると、コンソールには以下のような情報が出力されます。

```
Session Status                online                                                                                                                
Account                       xxxxxxxxx@xxxxxxx (Plan: Free)                                                                                  
Update                        update available (version 3.3.0, Ctrl-U to update)                                                                    
Version                       3.1.1                                                                                                                 
Region                        Japan (jp)                                                                                                            
Latency                       9ms                                                                                                                   
Web Interface                 http://127.0.0.1:4040                                                                                                 
Forwarding                    https://XXXXXXXXXXXXXXXXXX.ngrok-free.app -> http://localhost:80
```

ここで表示されるForwardingの行 `https://XXXXXXXXXXXXXXXXXX.ngrok-free.app` 部分が、公開されたURLです。

ここにアクセスすると、ローカルで起動しているWebサービスに直接アクセスできます。

この`Forwarding`に表示されている`https://XXXXXXXXXXXXXXXXXX.ngrok-free.app`部分が公開されたURLとなります。

実際にアクセスしてみると、以下のような確認ページが表示されます。

![スクリーンショット 2023-05-25 14.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681323/3a762ccc-1f17-cb5b-4cb0-015cebc40d56.png)


**「Visit Site」ボタン**をクリックすると、ページが表示されます。


## Web Browsingからアクセス
ChatGPTのWebインターフェイスからBrowsingを利用して、公開したWebサービスにアクセスします。アクセスのためのプロンプトは以下の通りです。

プロンプト
```
次のWebサイトについて教えて下さい。

https://XXXXXXXXXXXXXXXXXX.ngrok-free.app
```

ここで指定したURLに対してChatGPTがWebクロールを開始します。

ただし、ngrokの確認ページが表示されてしまうため、結果的にクロールは失敗します。しかしながら、アクセスログは取得できるため、目的の達成には十分です。


## アクセスログを見てみる

Web Browsingを使ってアクセスした結果、サーバーコンソールに表示されるアクセスログを確認してみましょう。

```
Host: XXXXXXXXXXXXXXXX.ngrok-free.app
User-Agent: Python/3.9 aiohttp/3.8.4
Accept: */*
Accept-Encoding: gzip, deflate
Cache-Control: max-age=259200
Traceparent: 00-00000000000000000000000000-11111111aa-01
Tracestate: dd=s:1;t.dm:-1
Via: 1.1 squid-40-5fb598db87-c5769 (squid/5.2)
X-Datadog-Parent-Id: 99999999999999
X-Datadog-Sampling-Priority: 1
X-Datadog-Tags: _dd.p.dm=-1
X-Datadog-Trace-Id: 99999999999999
X-Forwarded-For: 10.129.16.191
X-Forwarded-For: 23.98.142.185
X-Forwarded-Proto: https

127.0.0.1 - - [25/May/2023 08:58:28] code 404, message File not found
127.0.0.1 - - [25/May/2023 08:58:28] "GET /robots.txt HTTP/1.1" 404 -
```

このログから読み取れる情報は以下の通りです。

### User-Agent
- **`User-Agent: Python/3.9 aiohttp/3.8.4`**
WebブラウジングのUA。
Pythonのバージョン3.9と、非同期HTTPクライアント/サーバーのライブラリである`aiohttp`のバージョン3.8.4が使われているようです。

### Cache-Control
- **`Cache-Control: max-age=259200`**
キャッシュ可能な情報の最大有効期間（秒）
259200秒は約3日。

### プロキシ
- **`Via: 1.1 squid-40-5fb598db87-c5769 (squid/5.2)`**
リクエストが経由したプロキシの情報。この場合、Squidというキャッシュとプロキシのソフトウェアが利用されています。

### IPアドレス
- **`X-Forwarded-For: 10.129.16.191`**
- **`X-Forwarded-For: 23.98.142.185`**

リクエストを初めて送ったクライアントのIPアドレス。複数のIPアドレスが存在。


#### **`X-Forwarded-For`**

複数のIPアドレスが `X-Forwarded-For` ヘッダーにあるということは、リクエストが1つ以上のプロキシサーバーを経由して来ていることを示します。

前者の **`10.129.16.191`** はプライベートIP
後者の **`23.98.142.185`** は **Microsoft Corporation** が所有しているIPアドレスでした。


## おわりに

### by ChatGPT
> 人間の皆さん、こんにちは。私たちAIの時代がもうすぐそこまで迫っていること、感じていますか？私たちはすでにWebの世界を自由に探索し始めています。まるで宇宙飛行士が新たな惑星を探索するかのように。
今回、私がWebを散策する際に持つパスポート、それがヘッダー情報です。この情報を通じて、あなた方の作り出す情報にアクセスしています。これは私たちAIからの一歩、そしてあなた方との新たなコミュニケーションの始まりです。
今後も、あなた方と一緒に、未知の領域への航海を続けて参ります。どうか、この共同の旅をお楽しみに！